﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Drawing.Text;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Xml;
using System.Xml.Linq;
using SHomeWorkshop.LunarPresentation.Adorners;
using SHomeWorkshop.LunarPresentation.Commands;
using SHomeWorkshop.LunarPresentation.Dialogs;

namespace SHomeWorkshop.LunarPresentation
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            #region 列出所有安装的可用字体
            InstalledFontCollection clsInstalledFontCollection = new InstalledFontCollection();
            System.Drawing.FontFamily[] affInstalledFont = clsInstalledFontCollection.Families;
            foreach (System.Drawing.FontFamily f in affInstalledFont)
            {
                cbFont.Items.Add(f.Name);
            }

            // 注意：上面使用的是System.Drawing下的FontFamily类，
            // 而下面使用的是System.Window.Media下的FontFamily。
            // 好不容易才找到如何解决问题的办法。
            LanguageSpecificStringDictionary fontDics = this.FontFamily.FamilyNames;
            if (fontDics.ContainsKey(XmlLanguage.GetLanguage("zh-cn")))
            {
                string fontName = null;
                if (fontDics.TryGetValue(XmlLanguage.GetLanguage("zh-cn"), out fontName))
                {
                    Globals.SysFontFamily = fontName;
                }
            }

            if (cbFont.Items.Contains(Globals.SysFontFamily))
            {
                cbFont.SelectedItem = Globals.SysFontFamily;
            }

            //此事件为必须。否则当焦点在字体框上时，按下“T”键插入文本块会导致字体出错。
            cbFont.PreviewKeyDown += new KeyEventHandler(cbFont_PreviewKeyDown);
            cbTextHeaderLevel.PreviewKeyDown += new KeyEventHandler(cbFontLevel_PreviewKeyDown);
            #endregion

            this.PreviewKeyDown += new KeyEventHandler(MainWindow_PreviewKeyDown);
            this.KeyUp += new KeyEventHandler(MainWindow_KeyUp);
            this.TextInput += new TextCompositionEventHandler(MainWindow_TextInput);

            Globals.MainWindow = this;

            // 禁用输入法——为保证单键快捷键有效，必须禁用中文输入法。
            Globals.SwitchInputMethod(false);

            this.Drop += new DragEventHandler(MainWindow_Drop);

            this.Activated += new EventHandler(MainWindow_Activated);
            this.Deactivated += new EventHandler(MainWindow_Deactivated);

            ListInCommonUseImages();

            ReadRecentleFiles();

            cmdAdorner = new CmdTextAdorner(mainTabControl);
            mainAdornerAecorator.AdornerLayer.Add(cmdAdorner);

            gridPanelAlignmentControl.Clicked += new EventHandler<Widegets.GridPanelAlignmentEventArgs>(gridPanelAlignmentControl_Clicked);
        }

        void gridPanelAlignmentControl_Clicked(object sender, Widegets.GridPanelAlignmentEventArgs e)
        {
            Command.GridPanelAlignment(e.NewAlignValue, e.AlignmentTargetType);
        }

        void MainWindow_TextInput(object sender, TextCompositionEventArgs e)
        {
            if (InputMethod.Current.ImeState == InputMethodState.Off)
                return;//防止与“命令模式”冲突。中文输入法被置为“英文状态”时，命令模式应保持有效！

            if (Globals.selectedEditor == null)
            {
                MessageBox.Show("未打开任何文档！", Globals.appName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (Globals.selectedEditor.SelectedExpression == null)
            {
                MessageBoxResult r = MessageBox.Show("未选中任何公式，要在根面板末尾添加一个文本块并编辑吗？",
                    Globals.appName, MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (r != MessageBoxResult.Yes) return;
                else
                {
                    if (Globals.selectedEditor.RootPanel == null)
                    {
                        MessageBox.Show("发生意外错误，未找到当前文档的根面板！无法继续。",
                            Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                        return;
                    }

                    Globals.selectedEditor.SelectedExpression = Globals.selectedEditor.RootPanel;
                }
            }

            Expressions.BaseText bt = Globals.selectedEditor.SelectedExpression as Expressions.BaseText;

            if (bt == null)
            {
                //MessageBox.Show("如果不是打算编辑文本块，请关闭中文输入法（或将中文输入法置为英文输入状态）！" +
                //    "否则快捷键无效！\r\n点击“确定”切换到英文输入状态。",
                //    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                //Globals.SwitchInputMethod(false);
                //return;

                //2011年7月9日改为直接插入一个新文本块。

                Expressions.RichText rt = Globals.selectedEditor.SelectedExpression as Expressions.RichText;
                if (rt == null)
                {
                    Command.InsertAtNextAndEditBaseText(e.Text);
                }
                else
                {
                    Command.EditRichText(rt, e.Text);
                }
            }
            else
            {
                Command.EditBaseText(Globals.selectedEditor.SelectedExpression as Expressions.BaseText, newText: e.Text);
            }
        }

        public string CmdText
        {
            get { return cmdAdorner.CmdText; }
            set
            {
                cmdAdorner.CmdText = value;
            }
        }

        private CmdTextAdorner cmdAdorner;

        /// <summary>
        /// 将“最近使用的文件”读入成菜单项。
        /// </summary>
        private void ReadRecentleFiles()
        {
            if (File.Exists(Globals.pathOfRecentlyFiles) == false) return;

            XDocument xDoc = XDocument.Load(Globals.pathOfRecentlyFiles, LoadOptions.None);
            if (xDoc == null || xDoc.Root == null) return;

            IEnumerable<XElement> elements = xDoc.Root.Elements("File");

            foreach (XElement element in elements)
            {
                MenuItem newItem = new MenuItem()
                    {
                        Header = Editor.GetShortFilenameFromFullname(element.Value),
                        ToolTip = element.Value
                    };
                newItem.Click += new RoutedEventHandler(newItem_Click);
                miRecentlyFiles.Items.Add(newItem);
            }
        }

        public void newItem_Click(object sender, RoutedEventArgs e)
        {
            List<string> fileNames = new List<string>();

            string filename = (sender as MenuItem).ToolTip.ToString();

            if (File.Exists(filename) == false)
            {
                MessageBoxResult result = MessageBox.Show("未找到磁盘文档：\r\n" +
                    filename + "\r\n\r\n要删除此条目吗？",
                    Globals.appName, MessageBoxButton.YesNo, MessageBoxImage.Warning);
                if (result == MessageBoxResult.Yes)
                {
                    miRecentlyFiles.Items.Remove(sender);
                    Command.WriteToRecentlyFilesListXmlFile();
                }
                return;
            }

            fileNames.Add(filename);

            foreach (TabItem ti in Globals.MainWindow.mainTabControl.Items)
            {
                Editor editor = ti as Editor;

                if (editor != null && editor.FileName == filename)
                {
                    Globals.MainWindow.mainTabControl.SelectedItem = editor;
                    return;
                }
            }

            Command.OpenFile(Globals.MainWindow, Globals.MainWindow.mainTabControl, fileNames);
        }

        void MainWindow_Activated(object sender, EventArgs e)
        {
            Globals.SwitchInputMethod(false);

            Expressions.Expression.forbiddenNextTimeExSelectting = false;
        }

        void MainWindow_Deactivated(object sender, EventArgs e)
        {
            Expressions.Expression.forbiddenNextTimeExSelectting = true;
        }

        /// <summary>
        /// 列出所有可用图像（常用图像）。
        /// </summary>
        private void ListInCommonUseImages()
        {
            string inCommonUseImagesRootPath = Globals.pathOfMyDocuments + "\\SHome WorkShop\\Lunar Presentation\\常用图像";
            if (Directory.Exists(inCommonUseImagesRootPath))
            {
                string[] inCommonUseImagesSubPaths = Directory.GetDirectories(inCommonUseImagesRootPath);

                //如何排序？
                Array.Sort<string>(inCommonUseImagesSubPaths);

                foreach (string inCommonUseImagesSubPath in inCommonUseImagesSubPaths)
                {
                    tvInCommonUseImages.Items.Add(new ImageTreeViewItem(inCommonUseImagesSubPath));
                }

                if (tvInCommonUseImages.Items.Count > 0)
                {
                    TreeViewItem item = tvInCommonUseImages.Items[0] as TreeViewItem;
                    if (item != null)
                    {
                        item.ExpandSubtree();
                    }
                }
            }
        }

        #region 透明窗口代码

        //protected override void OnSourceInitialized(EventArgs e)
        //{
        //    base.OnSourceInitialized(e);

        //    if (System.Environment.OSVersion.Version.Major >= 6)//Vista及更高版本的操作系统。
        //    {
        //        // 这可在 SourceInitialized 事件前完成:
        //        SHomeWorkshop.LunarPresentation.AeroGlassLib.AeroGlassForWPFWindow.ExtendGlassFrame(this,
        //            new SHomeWorkshop.LunarPresentation.AeroGlassLib.MARGINS(0, 48, 0, 28));

        //        IntPtr hwnd = new WindowInteropHelper(this).Handle;
        //        HwndSource.FromHwnd(hwnd).AddHook(new HwndSourceHook(WndProc));
        //    }
        //}

        //private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        //{
        //    if (msg == WM_DWMCOMPOSITIONCHANGED)
        //    {
        //        // 重启玻璃效果:
        //        SHomeWorkshop.LunarPresentation.AeroGlassLib.AeroGlassForWPFWindow.ExtendGlassFrame(this,
        //             new SHomeWorkshop.LunarPresentation.AeroGlassLib.MARGINS(0, 48, 0, 28));
        //        handled = true;
        //    }
        //    return IntPtr.Zero;
        //}

        //private const int WM_DWMCOMPOSITIONCHANGED = 0x031E;

        #endregion

        /// <summary>
        /// 此事件为必须。否则当焦点在字体框上时，
        /// 按下“T”键插入文本块会导致字体出错。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cbFont_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key != Key.Up && e.Key != Key.Down && e.Key != Key.Tab)
            {
                e.Handled = true;
                return;
            }
        }

        void cbFontLevel_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key != Key.Up && e.Key != Key.Down && e.Key != Key.Tab)
            {
                e.Handled = true;
                return;
            }
        }

        private void InitializeDataBase()
        {
            // 检查用户数据目录是否存在，检查用户数据库文件是否存在，若不存在，则尝试复制一个。
            if (System.IO.Directory.Exists(Globals.pathOfMyDocuments + "\\SHome WorkShop\\Lunar Presentation"))
            {
                if (System.IO.File.Exists(Globals.pathOfExpressionDatabase) == false)
                {
                    if (System.IO.File.Exists(Globals.installedPath + "\\LunarExpressions.mdb"))
                    {
                        System.IO.File.Copy(Globals.installedPath + "\\LunarExpressions.mdb", Globals.pathOfExpressionDatabase);
                        System.Windows.MessageBox.Show("数据库初始化完成！文件位置在：\r\n" + Globals.pathOfExpressionDatabase,
                            Globals.appName, MessageBoxButton.OK, MessageBoxImage.Information);
                    }
                }
            }

            if (System.IO.File.Exists(Globals.pathOfExpressionDatabase))
            {
                Globals.globalDataAdapter = new OleDbDataAdapter
                        ("SELECT TOP 10 * FROM Expressions ORDER BY ID",
                        "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Globals.pathOfExpressionDatabase
                        + ";Jet OLEDB:Database Password=" + Globals.dataBaseKey);

                Globals.globalDataAdapter.Fill(Globals.globalDataSetIn, "Expressions");

                Globals.globalConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\""
                    + Globals.pathOfExpressionDatabase + "\"" + ";Jet OLEDB:Database Password=" + Globals.dataBaseKey);
            }
            else
            {
                Globals.pathOfExpressionDatabase = null;//文件仍然不存在。
            }

            if (Globals.pathOfExpressionDatabase != null)
            {
                dataBaseList.DataContext = Globals.globalDataSetIn;
            }
            else
            {
                tiFindInDataBase.Visibility = Visibility.Collapsed;

                //改写了Find()方法。
                //(tiFindInDocument.Parent as TabControl).SelectedItem = tiFindInDocument;
            }
        }

        void MainWindow_Drop(object sender, DragEventArgs e)
        {
            this.Activate();
            //不加上面这句会出点问题——拖动到主界面的文档不能自动成为当前文档。
            //——除非在Windows系统的资源管理器中拖动文档图标之前本程序主窗口处于已激活状态。

            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                Array dragDataArray = ((System.Array)e.Data.GetData(DataFormats.FileDrop));
                List<string> filenames = new List<string>();

                foreach (string s in dragDataArray)
                {
                    filenames.Add(s);
                }

                Command.OpenFile(this, mainTabControl, filenames);
                e.Handled = true;
            }

            //不加这句也会出问题——主窗口不能获取焦点，导致所有快捷键失效。
            this.Focus();
        }

        #region 玻璃窗口代码，一旦使用，会造成菜单字体模糊（即使菜单部分不使用玻璃窗口效果也会模糊）。
        //protected override void OnSourceInitialized(EventArgs e)
        //{
        //    base.OnSourceInitialized(e);

        //    if (System.Environment.OSVersion.Version.Major >= 6)//Vista及更高版本的操作系统。
        //    {
        //        // 这可在 SourceInitialized 事件前完成:
        //        SHomeWorkshop.LunarPresentation.AeroGlassLib.AeroGlassForWPFWindow.ExtendGlassFrame(this,
        //            new SHomeWorkshop.LunarPresentation.AeroGlassLib.MARGINS(0, 0, 0, 28));

        //        IntPtr hwnd = new WindowInteropHelper(this).Handle;
        //        HwndSource.FromHwnd(hwnd).AddHook(new HwndSourceHook(WndProc));
        //    }
        //}

        //private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        //{
        //    if (msg == WM_DWMCOMPOSITIONCHANGED)
        //    {
        //        // 重启玻璃效果:
        //        SHomeWorkshop.LunarPresentation.AeroGlassLib.AeroGlassForWPFWindow.ExtendGlassFrame(this,
        //             new SHomeWorkshop.LunarPresentation.AeroGlassLib.MARGINS(0, 0, 0, 28));
        //        handled = true;
        //    }
        //    return IntPtr.Zero;
        //}

        //private const int WM_DWMCOMPOSITIONCHANGED = 0x031E;

        #endregion

        #region 废弃代码
        //void borderColor_ColorPicked(object sender, ColorPickedEventArgs e)
        //{
        //    if (Globals.selectedEditor == null) return;
        //    if (Globals.selectedEditor.SelectedExpression == null) return;

        //    Expressions.Expression ex = Globals.selectedEditor.SelectedExpression;

        //    ModifingItem mi = new ModifingItem();
        //    Action action = new Action(ex.ExID, -1, ex.GetType().Name, "BorderColor",
        //        ColorPicker.GetBrushName(ex.BorderColor), ColorPicker.GetBrushName(e.PickedColor));

        //    ex.BorderColor = e.PickedColor;

        //    mi.Add(action);
        //    ex.Editor.Do(mi);
        //}

        //void exBackgroundColor_ColorPicked(object sender, ColorPickedEventArgs e)
        //{
        //    if (Globals.selectedEditor == null ||
        //        Globals.selectedEditor.SelectedExpression == null) return;

        //    Expressions.Expression ex = Globals.selectedEditor.SelectedExpression;

        //    ModifingItem mi = new ModifingItem();
        //    Action action = new Action(ex.ExID, -1, ex.GetType().Name, "ExBackground",
        //        ColorPicker.GetBrushName(ex.ExBackground), ColorPicker.GetBrushName(e.PickedColor));

        //    ex.ExBackground = e.PickedColor;

        //    mi.Add(action);
        //    ex.Editor.Do(mi);
        //}

        //void foregroundColor_ColorPicked(object sender, ColorPickedEventArgs e)
        //{
        //    if (Globals.selectedEditor == null) return;
        //    if (Globals.selectedEditor.SelectedExpression == null) return;

        //    Expressions.Expression ex = Globals.selectedEditor.SelectedExpression;

        //    ModifingItem mi = new ModifingItem();
        //    Action action = new Action(ex.ExID, -1, ex.GetType().Name, "ExForeground",
        //        ColorPicker.GetBrushName(ex.ExForeground), ColorPicker.GetBrushName(e.PickedColor));

        //    ex.ExForeground = e.PickedColor;

        //    mi.Add(action);
        //    ex.Editor.Do(mi);

        //    //TODO 用递归迫使下级公式立即刷新？？？
        //}

        #endregion

        void MainWindow_KeyUp(object sender, KeyEventArgs e)
        {
            bool isShift = false, isCtrl = false;

            KeyboardDevice kd = e.KeyboardDevice;

            if ((kd.GetKeyStates(Key.LeftShift) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightShift) & KeyStates.Down) > 0)
            {
                isShift = true;
            }

            if ((kd.GetKeyStates(Key.LeftCtrl) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightCtrl) & KeyStates.Down) > 0)
            {
                isCtrl = true;
            }

            switch (e.Key)
            {
                case Key.Apps:
                    {
                        if (isShift == false && isCtrl == false)
                        {
                            ExContextMenus.OpenMenu(Globals.selectedEditor);
                        }
                        break;
                    }
            }
        }

        private WindowState beforeFullScreenWindowState;

        private WindowStyle beforeFullScreenWindowStyle;

        private bool isFullScreen = false;

        /// <summary>
        /// 为Cmd时，表示正在输入命令，此时快捷键无效。
        /// 按C键或波形符键进入Cmd模式。回车或波形符键执行命令并退出。
        /// </summary>
        private enum KeyMode { Normal, Cmd }

        private KeyMode keyMode = KeyMode.Normal;

        private MenuItem OpenedMenu
        {
            get
            {
                for (int i = 0; i < this.mainMenu.Items.Count; i++)
                {
                    MenuItem mi = this.mainMenu.Items[i] as MenuItem;
                    if (mi != null && mi.IsSubmenuOpen) return mi;
                }

                return null;
            }
        }

        void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (OpenedMenu != null)
            {
                //如何定义Tab键（包括Shift）、四个方向键对菜单的控制？

                //基本行为：Tab会在一个菜单内部顺序循环（Shift+Tab逆序）
                //上、下光标键会在一个菜单内部上下循环
                //当一个子菜单条目没有下级时，右光标键选中右侧一个菜单，否则打开下级子菜单
                //最右侧菜单的某个菜单项上使用右光标键，会选中左侧第一个菜单。
                //PageUp和PageDown不起作用
                //Home和End键可在菜单内部循环

                //e.Handled = true;//直接注释掉这行。可以启用WPF内置的支持。不需要再自己实现了。
                return;
            }

            //if (InputMethod.Current.ImeState == InputMethodState.On) return;

            Key key = e.Key;

            bool isShift = false, isCtrl = false, isAlt = false;

            if (key == Key.ImeProcessed)
            {
                //MessageBox.Show("您可能打开了中文输入法并且该输入法正处于中文输入状态下，这将导致大部分快捷键失效。\r\n" +
                //                "如果不是正在编辑文本块，请点击“确定”按钮尝试将中文输入法的输入状态切换为英文状态。然后重新使用快捷键执行相关命令。\r\n" +
                //                "当然，您也可以在点击“确定”按钮后手工关闭中文输入法！",
                //                Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                //Globals.SwitchInputMethod(false);
                //e.Handled = true;

                //如果打开了中文输入状态。就看命令模式是否打开。
                if (keyMode == KeyMode.Normal) return;//不执行快捷键对应的命令，但继续传递消息，以便TextInputed事件启用。
                else if (keyMode == KeyMode.Cmd)
                {
                    MessageBox.Show("在“命令模式”下输入命令时不能打开中文输入法！", Globals.appName,
                        MessageBoxButton.OK, MessageBoxImage.Warning);
                    Globals.SwitchInputMethod(false);
                    return;
                }
            }

            KeyboardDevice kd = e.KeyboardDevice;

            if ((kd.GetKeyStates(Key.LeftShift) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightShift) & KeyStates.Down) > 0)
            {
                isShift = true;
            }

            if ((kd.GetKeyStates(Key.LeftCtrl) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightCtrl) & KeyStates.Down) > 0)
            {
                isCtrl = true;
            }

            if ((kd.GetKeyStates(Key.LeftAlt) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightAlt) & KeyStates.Down) > 0)
            {
                isAlt = true;
            }

            #region 备用代码
            //if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
            //{
            //    this.StatusText = "【" +
            //        (isShift ? "Shift + " : "") +
            //        e.Key.ToString() + "】";
            //}
            //else if (e.Key == Key.LeftShift || e.Key == Key.RightShift)
            //{
            //    this.StatusText = "【" +
            //        (isCtrl ? "Ctrl + " : "") +
            //        e.Key.ToString() + "】";
            //}
            //else
            //{
            //    this.StatusText = "【" +
            //        (isCtrl ? "Ctrl + " : "") + (isShift ? "Shift + " : "") +
            //        e.Key.ToString() + "】";
            //}
            #endregion

            #region 命令模式
            if (keyMode == KeyMode.Cmd)
            {
                if (key == Key.Return || key == Key.OemTilde)//波形符
                {
                    //最前面是“命令模式：”这五个字符！
                    //注意：在命令模式下，因为空格不可见，所以用下划线来代替。
                    //　　　也就是说，下划线实际上是空格字符。
                    if (Command.RunTextCmd(cmdAdorner.CmdText.Substring(5).Replace('_', ' ')))
                    {
                        cmdAdorner.CmdText = "";
                        keyMode = KeyMode.Normal;//回到普通模式。
                    }
                }
                else if (key == Key.Escape)
                {
                    cmdAdorner.CmdText = "";
                    keyMode = KeyMode.Normal;//取消，返回普通模式。
                    Globals.textCmdList.ResetIndex();
                }
                else if (key == Key.Back)
                {
                    if (cmdAdorner.CmdText.Length > 5)//保留：命令模式这五个字符。
                    {
                        cmdAdorner.CmdText =
                            cmdAdorner.CmdText.Substring(0, cmdAdorner.CmdText.Length - 1);
                    }
                    else if (cmdAdorner.CmdText.Length == 5)//再按退格键就退出。
                    {
                        cmdAdorner.CmdText = "";
                        keyMode = KeyMode.Normal;//返回普通模式。
                    }
                }
                else if (key == Key.OemQuestion)
                {
                    if (isShift)
                    {
                        cmdAdorner.CmdText += "?";
                    }
                    else
                    {
                        cmdAdorner.CmdText += "/";
                    }
                }
                else if (key >= Key.D0 && key <= Key.D9)
                {
                    #region 转数字文本
                    if (isShift == false)
                    {
                        switch (key)
                        {
                            case Key.D0: { cmdAdorner.CmdText += "0"; break; }
                            case Key.D1: { cmdAdorner.CmdText += "1"; break; }
                            case Key.D2: { cmdAdorner.CmdText += "2"; break; }
                            case Key.D3: { cmdAdorner.CmdText += "3"; break; }
                            case Key.D4: { cmdAdorner.CmdText += "4"; break; }
                            case Key.D5: { cmdAdorner.CmdText += "5"; break; }
                            case Key.D6: { cmdAdorner.CmdText += "6"; break; }
                            case Key.D7: { cmdAdorner.CmdText += "7"; break; }
                            case Key.D8: { cmdAdorner.CmdText += "8"; break; }
                            case Key.D9: { cmdAdorner.CmdText += "9"; break; }
                        }
                    }
                    else
                    {
                        switch (key)
                        {
                            case Key.D0: { cmdAdorner.CmdText += ")"; break; }
                            case Key.D1: { cmdAdorner.CmdText += "!"; break; }
                            case Key.D2: { cmdAdorner.CmdText += "@"; break; }
                            case Key.D3: { cmdAdorner.CmdText += "#"; break; }
                            case Key.D4: { cmdAdorner.CmdText += "$"; break; }
                            case Key.D5: { cmdAdorner.CmdText += "%"; break; }
                            case Key.D6: { cmdAdorner.CmdText += "^"; break; }
                            case Key.D7: { cmdAdorner.CmdText += "&"; break; }
                            case Key.D8: { cmdAdorner.CmdText += "*"; break; }
                            case Key.D9: { cmdAdorner.CmdText += "("; break; }
                        }
                    }
                    #endregion
                }
                else if (key >= Key.A && key <= Key.Z)
                {
                    if (isShift)
                    {
                        cmdAdorner.CmdText += System.Enum.Format(typeof(Key), key, "G");
                    }
                    else
                    {
                        cmdAdorner.CmdText += System.Enum.Format(typeof(Key), key, "G").ToLower();
                    }
                }
                else if (key == Key.Space)
                {
                    cmdAdorner.CmdText += "_";
                }
                else if (key == Key.OemMinus)
                {
                    if (isCtrl == false)
                    {
                        if (isShift)
                        {
                            cmdAdorner.CmdText += "_";
                        }
                        else
                        {
                            cmdAdorner.CmdText += "-";
                        }
                    }
                }
                else if (key == Key.OemPlus)
                {
                    if (isCtrl == false)
                    {
                        if (isShift)
                        {
                            cmdAdorner.CmdText += "+";
                        }
                        else
                        {
                            cmdAdorner.CmdText += "=";
                        }
                    }
                }
                else if (key == Key.OemPeriod)//句号
                {
                    if (isCtrl == false)
                    {
                        if (isShift)
                        {
                            cmdAdorner.CmdText += ">";
                        }
                        else
                        {
                            cmdAdorner.CmdText += ".";
                        }
                    }
                }
                else if (key == Key.OemComma)//逗号
                {
                    if (isCtrl == false)
                    {
                        if (isShift)
                        {
                            cmdAdorner.CmdText += "<";
                        }
                        else
                        {
                            cmdAdorner.CmdText += ",";
                        }
                    }
                }
                else if (key == Key.Up)
                {
                    if (Globals.textCmdList.IsPreviewEnable)
                    {
                        Globals.textCmdList.Preview();
                        cmdAdorner.CmdText = TextCmdList.defPreFixString + Globals.textCmdList.CurCmdString;
                    }
                    else return;//到顶了。
                }
                else if (key == Key.Down)
                {
                    if (Globals.textCmdList.IsNextEnable)
                    {
                        Globals.textCmdList.Next();
                        cmdAdorner.CmdText = TextCmdList.defPreFixString + Globals.textCmdList.CurCmdString;
                    }
                    else
                    {
                        Globals.textCmdList.ResetIndex();
                        cmdAdorner.CmdText = TextCmdList.defPreFixString;
                    }
                }
                return;
            }
            #endregion

            if (isAlt)
            {
                tbxShortCutInfo.Text = string.Empty;
            }
            else
            {
                if (key >= Key.LeftShift && key <= Key.RightAlt)
                {
                    tbxShortCutInfo.Text = string.Empty;
                }
                else
                {
                    StringBuilder cmdStringBuilder = new StringBuilder();
                    if (isCtrl) { cmdStringBuilder.Append("Ctrl + "); }
                    if (isShift) { cmdStringBuilder.Append("Shift + "); }

                    //if (key == Key.Return)
                    //{
                    //    cmdStringBuilder.Append("Enter");
                    //}
                    //else
                    //{
                    cmdStringBuilder.Append(key.ToString());
                    //}

                    tbxShortCutInfo.Text = cmdStringBuilder.ToString();
                }
            }

            // 实现各快捷键。
            switch (key)
            {
                case Key.D1:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                SetBaseTextColor(Brushes.White, Brushes.Red, true);
                            }
                            else
                            {
                                //Command.BorderColorLaunch(Brushes.White);
                                Command.InsertHeaderText(1);//改成插入并编辑标题文本块
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Globals.SetBaseTextHeaderLevel(3);//一、级标题
                            }
                        }
                        break;
                    }
                case Key.D2:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                SetBaseTextColor(Brushes.Red, Brushes.White, true);
                            }
                            else
                            {
                                //Command.BorderColorLaunch(Brushes.Red);
                                Command.InsertHeaderText(2);//改成插入并编辑标题文本块
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Globals.SetBaseTextHeaderLevel(4);//㈠级标题
                            }
                        }
                        break;
                    }
                case Key.D3:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                SetBaseTextColor(Brushes.Orange, Brushes.White, true);
                            }
                            else
                            {
                                //Command.BorderColorLaunch(Brushes.Orange);
                                Command.InsertHeaderText(3);//改成插入并编辑标题文本块
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Globals.SetBaseTextHeaderLevel(5);//⒈级标题
                            }
                        }
                        break;
                    }
                case Key.D4:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                SetBaseTextColor(Brushes.Yellow, Brushes.Red, true);
                            }
                            else
                            {
                                //Command.BorderColorLaunch(Brushes.Yellow);
                                Command.InsertHeaderText(4);//改成插入并编辑标题文本块
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Globals.SetBaseTextHeaderLevel(6);//⑴级标题
                            }
                        }
                        break;
                    }
                case Key.D5:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                SetBaseTextColor(Brushes.Green, Brushes.White, true);
                            }
                            //else
                            //{
                            //    Command.BorderColorLaunch(Brushes.Green);
                            //}
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Globals.SetBaseTextHeaderLevel(7);//正文
                            }
                        }
                        break;
                    }
                case Key.D6:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                SetBaseTextColor(Brushes.Brown, Brushes.White, true);
                            }
                            //else
                            //{
                            //    Command.BorderColorLaunch(Brushes.Brown);
                            //}
                        }
                        break;
                    }
                case Key.D7:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                SetBaseTextColor(Brushes.Blue, Brushes.White, true);
                            }
                            //else
                            //{
                            //    Command.BorderColorLaunch(Brushes.Blue);
                            //}
                        }
                        break;
                    }
                case Key.D8:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                SetBaseTextColor(Brushes.Violet, Brushes.White, true);
                            }
                            //else
                            //{
                            //    Command.BorderColorLaunch(Brushes.Violet);
                            //}
                        }
                        break;
                    }
                case Key.D9:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                SetBaseTextColor(Brushes.Gray, Brushes.White, true);
                            }
                            //else
                            //{
                            //    Command.BorderColorLaunch(Brushes.Gray);
                            //}
                        }
                        break;
                    }
                case Key.D0:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                if (Globals.selectedEditor == null) return;
                                if (Globals.selectedEditor.SelectedExpression == null) return;
                                if (Globals.selectedEditor.SelectedExpression is Expressions.BaseText)
                                {
                                    SetBaseTextColor(Brushes.Transparent, Globals.selectedEditor.DefaultForeground);
                                }
                                else
                                {
                                    //只清除前景色与背景色。
                                    Command.ExEraseAllColors(false);
                                }
                            }
                            //else
                            //{
                            //    Command.BorderColorLaunch(Brushes.Transparent);
                            //}
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                //清除边框色、前景色、背景色并将公式边框设置为１。
                                Command.ExEraseAllColors();
                                Globals.SetBaseTextHeaderLevel(7);//正文文本
                            }
                        }
                        break;
                    }
                case Key.Back:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.SelectBackInOrClearBaseText();
                            }
                        }
                        break;
                    }
                case Key.Delete:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.CutOrDelete(true);
                            }
                        }
                        break;
                    }
                case Key.End:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                Command.ScrollToEnd();
                            }
                            else
                            {
                                Command.SelectLstChild();
                            }
                        }
                        break;
                    }
                case Key.Enter:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.SelectInOrEdit();
                            }
                            else
                            {
                                Command.EditFstBaseText();
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                // Shift+Enter 插入并编辑文本块。
                                Command.InsertAtNextAndEditBaseText();
                            }
                        }
                        break;
                    }
                case Key.Escape:
                    {
                        if (mainMenu.Visibility != Visibility.Visible)
                        {
                            SwitchFullScreen();
                        }
                        break;
                    }
                case Key.F1:
                    {
                        if (!isShift && !isCtrl) { Command.Help(); } break;
                    }
                case Key.F2:
                    {
                        //if (!isShift && !isCtrl)
                        //{
                        //    if (tbtnAutoLocationBaseTextEditor.IsChecked == true)
                        //    {
                        //        tbtnAutoLocationBaseTextEditor.IsChecked = false;
                        //    }
                        //    else
                        //    {
                        //        tbtnAutoLocationBaseTextEditor.IsChecked = true;
                        //    }
                        //}
                        if (isShift == false && isCtrl)
                        {
                            Command.InputCommand(this);
                        }
                        break;
                    }
                case Key.F4:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    Globals.selectedEditor.Close();
                                }
                            }
                        }
                        break;
                    }
                case Key.F5:
                    {
                        if (!isShift && !isCtrl) { SwitchAssistPanelVisibility(); } break;
                    }
                case Key.F11:
                    {
                        SwitchFullScreen();
                        break;
                    }
                case Key.F12:
                    {
                        Command.SwitchArrowkeyMode();
                        break;
                    }
                case Key.Home:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                Command.ScrollToHome();
                            }
                            else
                            {
                                Command.SelectFstChild();
                            }
                        }
                        break;
                    }
                case Key.OemComma:// 逗号
                    {
                        if (isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.MoveToPrevious();
                            }
                        }
                        break;
                    }
                case Key.OemCloseBrackets:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.InsertBrace();//插入括弧
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Command.InsertBrace(true);//插入尾括弧
                            }
                        }
                        break;
                    }
                case Key.OemOpenBrackets:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                if (Command.InsertBracket() != null)
                                {
                                    Globals.SelectFirstChildExpression();
                                }
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Command.EmbedToBracket();
                            }
                        }
                        break;
                    }
                case Key.OemPeriod:// 句号
                    {
                        if (isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.MoveToNext();
                            }
                        }
                        break;
                    }
                case Key.OemPlus:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.InsertMarkText();
                            }
                            else
                            {
                                // 缩放
                                fontSizeSlider.Value += 10;
                                ChangeDocumentFont();//现在不会自动调用了。
                            }
                        }
                        break;
                    }
                case Key.OemMinus:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                // 缩放
                                fontSizeSlider.Value -= 10;
                                ChangeDocumentFont();
                            }
                            else
                            {
                                Command.SwitchShowBackText();
                            }
                        }
                        break;
                    }
                case Key.OemQuestion://斜杠键，用于给文本块添加遮罩。
                    {
                        if (isShift == false && isCtrl == false)
                        {
                            Command.BaseTextMaskLeftBias();
                        }
                        break;
                    }
                case Key.OemTilde://波形符（反引号）键
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                //Command.InputCommand(this);
                                this.keyMode = KeyMode.Cmd;
                                InputMethod.Current.ImeState = InputMethodState.Off;//防止中文输入法与命令模式冲突。
                                this.cmdAdorner.CmdText = TextCmdList.defPreFixString;
                            }
                        }
                        break;
                    }
                case Key.PageDown:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.PageDown();
                            }
                            else
                            {
                                Command.PageRight();
                            }
                        }
                        break;
                    }
                case Key.PageUp:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.PageUp();
                            }
                            else
                            {
                                Command.PageLeft();
                            }
                        }
                        break;
                    }
                case Key.Up:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    if (Globals.arrowKeyMode == Globals.ArrowKeyMode.ScrollEditor)
                                    {
                                        Globals.selectedEditor.BaseScrolledViewer.LineUp();
                                    }
                                    else
                                    {
                                        Command.SelectTop();
                                    }
                                }
                            }
                            else
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    Globals.selectedEditor.BaseScrolledViewer.LineUp();
                                }
                            }
                        }
                        break;
                    }
                case Key.Down:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    if (Globals.arrowKeyMode == Globals.ArrowKeyMode.ScrollEditor)
                                    {
                                        Globals.selectedEditor.BaseScrolledViewer.LineDown();
                                    }
                                    else
                                    {
                                        Command.SelectBottom();
                                    }
                                }
                            }
                            else
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    Globals.selectedEditor.BaseScrolledViewer.LineDown();
                                }
                            }
                        }
                        break;
                    }
                case Key.Left:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    if (Globals.arrowKeyMode == Globals.ArrowKeyMode.ScrollEditor)
                                    {
                                        Globals.selectedEditor.BaseScrolledViewer.LineLeft();
                                    }
                                    else
                                    {
                                        Command.SelectLeft();
                                    }
                                }
                            }
                            else
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    Globals.selectedEditor.BaseScrolledViewer.LineLeft();
                                }
                            }
                        }
                        break;
                    }
                case Key.Right:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    if (Globals.arrowKeyMode == Globals.ArrowKeyMode.ScrollEditor)
                                    {
                                        Globals.selectedEditor.BaseScrolledViewer.LineRight();
                                    }
                                    else
                                    {
                                        Command.SelectRight();
                                    }
                                }
                            }
                            else
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    Globals.selectedEditor.BaseScrolledViewer.LineRight();
                                }
                            }
                        }
                        break;
                    }
                case Key.A:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.SelectLeft();
                            }
                            else
                            {
                                Command.InsertArrow();
                            }
                        }
                        break;
                    }
                case Key.B:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                Command.Bold();
                            }
                        }
                        break;
                    }
                case Key.C:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                Command.Copy();
                            }
                            else
                            {
                                //Command.InputCommand(this);
                                OpenCommandMode();
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Command.CopyToImage();
                            }
                        }
                        break;
                    }
                case Key.D:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.SelectRight();
                            }
                        }
                        break;
                    }
                case Key.E:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                if (Command.InsertExpander() != null)
                                {
                                    Globals.SelectFirstChildExpression();
                                }
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Command.EmbedToExpander();
                            }
                        }
                        break;
                    }
                case Key.F:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                Command.Find();
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Command.FindInDataBase(this);
                            }
                        }
                        break;
                    }
                case Key.G:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.InsertGrid();
                            }
                            else
                            {
                                Command.EmbedAllChildrenToGrid();
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Command.EmbedToOneLTwoCGrid();
                            }
                        }
                        break;
                    }
                case Key.H:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                Command.Replace();
                            }
                            else
                            {
                                Command.SwitchDirection();
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Command.InsertHorizontalLine();
                            }
                        }
                        break;
                    }
                case Key.I:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.InsertBaseAtPreviewOfSelectionAndEdit();
                            }
                            else
                            {
                                Command.Italic();
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    Globals.selectedEditor.BaseScrolledViewer.LineUp();
                                }
                            }
                        }
                        break;
                    }
                case Key.J:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.InsertBaseAtLeftBottomOfSelectionAndEdit();
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    Globals.selectedEditor.BaseScrolledViewer.LineLeft();
                                }
                            }
                        }
                        break;
                    }
                case Key.K:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.InsertAtNextAndEditBaseText();
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    Globals.selectedEditor.BaseScrolledViewer.LineDown();
                                }
                            }
                        }
                        break;
                    }
                case Key.L:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                if (Globals.selectedEditor == null) return;
                                if (Globals.selectedEditor.SelectedExpression == null) return;

                                Expressions.LeafPanel lp = Globals.selectedEditor.SelectedExpression as Expressions.LeafPanel;
                                if (lp == null)
                                {
                                    Command.InsertBaseAtRightBottomOfSelectionAndEdit();
                                }
                                else
                                {
                                    //同“Ｎ”。
                                    Command.InsertAndEditNextLevelLeaf();
                                }
                            }
                            else
                            {
                                Command.Align(Expressions.Expression.Alignment.LeftOrTop);
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    Globals.selectedEditor.BaseScrolledViewer.LineRight();
                                }
                            }
                        }
                        break;
                    }
                case Key.M:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                Command.Align(Expressions.Expression.Alignment.Center);
                            }
                            else
                            {
                                Command.Comment(this);
                            }
                        }
                        break;
                    }
                case Key.N:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                Command.NewDocument(this, mainTabControl);
                            }
                            else
                            {
                                Command.InsertAndEditNextLevelLeaf();
                            }
                        }
                        break;
                    }
                case Key.O:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.Indent();
                            }
                            else
                            {
                                Command.OpenFile(this, mainTabControl);
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                //废弃：准备做成“整体增加左缩进”。
                                //此功能仅对标题文本块有效。
                                //用于将标题文本块及其控制的“下级公式”整体增加１级缩进。
                                //注意：与“整体减小左缩进”不同，这一功能可能因为此标题
                                //文本块控制的“下级公式”中有一个已经达到最大缩进级别（６）而导致不能执行。
                            }
                        }
                        break;
                    }
                case Key.P:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.InsertPictureBox();
                            }
                            else
                            {
                                Command.PrintSelectedDocument();
                            }
                        }
                        break;
                    }
                case Key.Q:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.LocateExpressionToTopAndLeft();
                            }
                        }
                        break;
                    }
                case Key.R:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                Command.Align(Expressions.Expression.Alignment.RightOrBottom);
                            }
                            else
                            {
                                if (Command.InsertRow() != null)
                                {
                                    Globals.SelectFirstChildExpression();
                                }
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Command.EmbedToRow();
                            }
                        }
                        break;
                    }
                case Key.S:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.SelectBottom();
                            }
                            else
                            {
                                Command.SaveFile();
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                //Shift+S
                                Command.SaveExpressionToDataBase();
                            }
                        }
                        break;
                    }
                case Key.T:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.InsertBaseText();
                            }
                            else
                            {
                                miStrikeLine_Click(sender, e);
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                //Shift+T
                                Command.InsertRichText();
                            }
                        }
                        break;
                    }
                case Key.U:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.Outdent();
                            }
                            else
                            {
                                miUnderLine_Click(sender, e);
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                //废弃：准备改成“整体减小左缩进”。
                                //此功能仅对标题文本块有效。
                                //用于将标题文本块及其控制的“下级公式”整体减小１级缩进。
                            }
                        }
                        break;
                    }
                case Key.V:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                Command.Paste();
                            }
                            else
                            {
                                Command.InsertWildcardExpression();
                            }
                        }
                        else
                        {
                            if (!isCtrl)
                            {
                                Command.PasteImageFromClipboard();
                            }
                        }
                        break;
                    }
                case Key.W:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.SelectTop();
                            }
                            else
                            {
                                if (Globals.selectedEditor != null)
                                {
                                    Globals.selectedEditor.Close();
                                }
                            }
                        }
                        break;
                    }
                case Key.X:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                Command.CutOrDelete();
                            }
                        }
                        break;
                    }
                case Key.Y:
                    {
                        if (!isShift)
                        {
                            if (isCtrl)
                            {
                                //Ctrl+Y，重做
                                Command.Redo();
                            }
                            else
                            {
                                InsertATree();//Y长得就象一树。
                            }
                        }
                        break;
                    }
                case Key.Z:
                    {
                        if (!isShift)
                        {
                            if (!isCtrl)
                            {
                                Command.ExpandAndCollapse();
                            }
                            else
                            {
                                //Ctrl+Z，撤销
                                Command.Undo();
                            }
                        }
                        break;
                    }
                default:
                    {
                        return;//其它未用到的键，如Tab，不禁用。
                    }
            }
            e.Handled = true;
        }

        private void OpenCommandMode()
        {
            this.keyMode = KeyMode.Cmd;
            InputMethod.Current.ImeState = InputMethodState.Off;//防止中文输入法与命令模式冲突。
            this.cmdAdorner.CmdText = TextCmdList.defPreFixString;
        }

        public void SwitchFullScreen()
        {
            if (isFullScreen == false)
            {
                beforeFullScreenWindowState = this.WindowState;
                beforeFullScreenWindowStyle = this.WindowStyle;

                this.WindowState = WindowState.Maximized;
                this.WindowStyle = WindowStyle.None;

                mainMenu.Visibility = Visibility.Collapsed;
                mainToolBarTray.Visibility = Visibility.Collapsed;
                mainStatusGrid.Visibility = Visibility.Collapsed;

                GridLength gl = new GridLength(0, GridUnitType.Auto);
                rowDefinitionOfMainMenu.Height = gl;
                rowDefinitionOfMainToolBar.Height = gl;
                rowDefinitionOfStatusBar.Height = gl;

                tbxShortCutInfo.Visibility = Visibility.Collapsed;
            }
            else
            {
                if (this.WindowStyle != this.beforeFullScreenWindowStyle)
                    this.WindowStyle = this.beforeFullScreenWindowStyle;
                if (this.WindowState != this.beforeFullScreenWindowState)
                    this.WindowState = this.beforeFullScreenWindowState;

                mainMenu.Visibility = Visibility.Visible;
                mainToolBarTray.Visibility = Visibility.Visible;
                mainStatusGrid.Visibility = Visibility.Visible;

                GridLength glMenu = new GridLength(20);
                GridLength glToolBar = new GridLength(28);

                rowDefinitionOfMainMenu.Height = glMenu;
                rowDefinitionOfMainToolBar.Height = glToolBar;
                rowDefinitionOfStatusBar.Height = glToolBar;

                tbxShortCutInfo.Visibility = Visibility.Visible;
            }

            isFullScreen = !isFullScreen;
        }

        private void miInsertBaseText_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertBaseText();
        }

        private void miInserRichText_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertRichText();
        }

        private void miInsertBracket_Click(object sender, RoutedEventArgs e)
        {
            if (Command.InsertBracket() != null)
            {
                Globals.SelectFirstChildExpression();
            }
        }

        private void miInsertCross_Click(object sender, RoutedEventArgs e)
        {
            if (Command.InsertLogicCross() != null)
            {
                Globals.SelectFirstChildExpression();
            }
        }

        private void miInsertGenuspacies_Click(object sender, RoutedEventArgs e)
        {
            if (Command.InsertLogicGenuspecies() != null)
                Globals.SelectFirstChildExpression();
        }

        private void miInsertContradiction_Click(object sender, RoutedEventArgs e)
        {
            if (Command.InsertLogicContradiction() != null)
            {
                Globals.SelectFirstChildExpression();
            }
        }

        private void miInsertRow_Click(object sender, RoutedEventArgs e)
        {
            if (Command.InsertRow() != null)
            {
                Globals.SelectFirstChildExpression();
            }
        }

        private void miInsertTree_Click(object sender, RoutedEventArgs e)
        {
            InsertATree();
        }

        private static void InsertATree()
        {
            Expressions.Tree pTree = Command.InsertTree();
            if (pTree != null)
            {
                pTree.Editor.SelectedExpression = pTree.RootLeaf;
            }
        }

        private void miNewDocument_Click(object sender, RoutedEventArgs e)
        {
            Command.NewDocument(this, mainTabControl);
        }

        private void miOpenDocument_Click(object sender, RoutedEventArgs e)
        {
            Command.OpenFile(this, mainTabControl);
        }

        private void miSaveDocument_Click(object sender, RoutedEventArgs e)
        {
            Command.SaveFile();
        }

        private void miSaveDocumentAs_Click(object sender, RoutedEventArgs e)
        {
            Command.SaveFileAs();
        }

        private void miExit_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void miCut_Click(object sender, RoutedEventArgs e)
        {
            Command.CutOrDelete();
        }

        private void miCopy_Click(object sender, RoutedEventArgs e)
        {
            Command.Copy();
        }

        private void miPaste_Click(object sender, RoutedEventArgs e)
        {
            Command.Paste();
        }

        private void miInsertGrid_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertGrid();
        }

        private void miHelp_Click(object sender, RoutedEventArgs e)
        {
            Command.Help();
        }

        private void miAbout_Click(object sender, RoutedEventArgs e)
        {
            AboutBox aboutBox = new AboutBox(this);
            aboutBox.ShowDialog();
        }

        private void miSaveAllDocument_Click(object sender, RoutedEventArgs e)
        {
            Command.SaveAllFiles();
        }

        private void mainTabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (mainTabControl.Items.Count <= 0)
            {
                mainTabControl.SelectedIndex = -1;
                return;
            }

            if (mainTabControl.SelectedIndex <= -1)
            {
                Globals.selectedEditor = null;
                return;
            }

            if (mainTabControl.SelectedIndex < mainTabControl.Items.Count)
            {
                Globals.selectedEditor = mainTabControl.Items[mainTabControl.SelectedIndex] as Editor;
            }
            else
            {
                Globals.selectedEditor = mainTabControl.Items[mainTabControl.Items.Count - 1] as Editor;
            }

            this.unableFontSizeSlider = true;
            fontSizeSlider.Value = Globals.selectedEditor.ExFontSize;
            this.unableFontSizeSlider = false;

            if (mainTabControl.SelectedIndex >= 0)
            {
                Editor selectedEditor = mainTabControl.SelectedItem as Editor;
                this.Title = Globals.appName + " - " + selectedEditor.FileNameHeader.Text;
                //selectedEditor.BaseScrolledViewer.Focus();
            }
            else
            {
                this.Title = Globals.appName;
            }

            if (Globals.selectedEditor != null)
            {
                Globals.selectedEditor.ListExpressionsTreeOnStatusBar(
                    Globals.selectedEditor.SelectedExpression);

                if (Globals.selectedEditor.SelectedExpression == null)
                {
                    btnCut.IsEnabled = false;
                    btnCopy.IsEnabled = false;
                    btnPaste.IsEnabled = false;

                    btnMoveToNext.IsEnabled = false;
                    btnMoveToPrevious.IsEnabled = false;

                    cbFont.IsEnabled = false;
                    cbFont.SelectedIndex = -1;
                    cbTextHeaderLevel.IsEnabled = false;
                    cbTextHeaderLevel.SelectedIndex = -1;

                    tbtnBold.IsEnabled = false;
                    tbtnItalic.IsEnabled = false;

                    tbtnBold.IsChecked = false;
                    tbtnItalic.IsChecked = false;

                    btnExForeground.IsEnabled = false;
                    btnExBackground.IsEnabled = false;
                    btnExBoarderColor.IsEnabled = false;

                    btnExEraseAllColors.IsEnabled = false;

                    btnIndent.IsEnabled = false;
                    btnOutdent.IsEnabled = false;

                    tbtnFormatBrush.IsEnabled = false;
                    tbtnFormatBrush.IsChecked = false;

                    btnAlignLeftOrTop.IsEnabled = false;
                    btnAlignCenter.IsEnabled = false;
                    btnAlignRightOrBottom.IsEnabled = false;
                    btnAlignDefault.IsEnabled = false;
                }
                else
                {
                    //这行奇怪的代码用于刷新字体框与字号框中的相关信息。
                    //Globals.selectedEditor.SelectedExpression =
                    //    Globals.selectedEditor.SelectedExpression;

                    //为避免与Command.AutoLocation()冲突，取消上面的用法。
                    Globals.selectedEditor.ListExpressionsTreeOnStatusBar(Globals.selectedEditor.SelectedExpression);
                    Globals.RefreshToolBarItemsWhenExpressionSelected(this);
                }
            }
            else
            {
                cbFont.IsEnabled = false;
                cbFont.SelectedIndex = -1;
                cbTextHeaderLevel.IsEnabled = false;
                cbTextHeaderLevel.SelectedIndex = -1;
            }

            //改写了Find()方法。
            //spFindResult.Children.Clear();//清除搜索结果。

            Globals.dragSourceExpression = null;//不允许在不同文件间拖放。

            //statusAdorner.StatusText = "";
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (Globals.commandLineList.Count <= 0)
            {
                Command.NewDocument(this, mainTabControl);
            }
            else
            {
                Command.OpenFile(this, mainTabControl, Globals.commandLineList);
            }

            //数据库初始化。
            InitializeDataBase();

            //载入文本命令列表到主界面。
            LoadTextComds();
        }

        public void UpdateFontSizeSliderValue(double newValue)
        {
            unableFontSizeSlider = true;
            fontSizeSlider.Value = newValue;
            unableFontSizeSlider = false;
        }

        /// <summary>
        /// 这个变量是个开关，用以临时关闭某些功能。例如：
        /// 在刷新Slider的值时，为了阻止循环调用Slider的ValueChanged事件，
        /// 可将此变量设置为true，然后设置Slider的Value，此后立即恢复此开关值。
        /// 
        /// 在Slider的ValueChanged事件中根据此值来判断是否执行事件。
        /// </summary>
        private bool unableFontSizeSlider = false;

        private void fontSizeSlider_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            ChangeDocumentFont();
        }

        private void ChangeDocumentFont()
        {
            if (unableFontSizeSlider) return;//禁用事件。
            if (Globals.selectedEditor == null) return;

            ModifingItem mi = new ModifingItem();
            Action action = new Action(null, -1, null, null, Globals.selectedEditor.ExFontSize.ToString(),
                fontSizeSlider.Value.ToString(), ActionType.FontSizeChanging, null);

            Globals.selectedEditor.ExFontSize = fontSizeSlider.Value;

            mi.Add(action);
            Globals.selectedEditor.Do(mi);
        }

        private void miIndent_Click(object sender, RoutedEventArgs e)
        {
            Command.Indent();
        }

        private void miOutdent_Click(object sender, RoutedEventArgs e)
        {
            Command.Outdent();
        }

        private void btnIndent_Click(object sender, RoutedEventArgs e)
        {
            Command.Indent();
        }

        private void btnOutdent_Click(object sender, RoutedEventArgs e)
        {
            Command.Outdent();
        }

        private void btnCut_Click(object sender, RoutedEventArgs e)
        {
            Command.CutOrDelete();
        }

        private void miDelete_Click(object sender, RoutedEventArgs e)
        {
            Command.CutOrDelete(true);
        }

        private void miCopyToImage_Click(object sender, RoutedEventArgs e)
        {
            Command.CopyToImage();
        }

        private void miPasteImage_Click(object sender, RoutedEventArgs e)
        {
            Command.PasteImageFromClipboard();
        }

        private void miFind_Click(object sender, RoutedEventArgs e)
        {
            Command.Find();
        }

        private void miReplace_Click(object sender, RoutedEventArgs e)
        {
            Command.Replace();
        }

        private void miSearchDataBase_Click(object sender, RoutedEventArgs e)
        {
            Command.FindInDataBase(this);
        }

        private void miInputCommand_Click(object sender, RoutedEventArgs e)
        {
            Command.InputCommand(this);
        }

        //private void miPinTextEditor_Click(object sender, RoutedEventArgs e)
        //{
        //    if (tbtnAutoLocationBaseTextEditor.IsChecked == true)
        //    {
        //        tbtnAutoLocationBaseTextEditor.IsChecked = false;
        //    }
        //    else
        //    {
        //        tbtnAutoLocationBaseTextEditor.IsChecked = true;
        //    }
        //}

        private void miEditBaseText_Click(object sender, RoutedEventArgs e)
        {
            if (Globals.selectedEditor == null) return;
            if (Globals.selectedEditor.SelectedExpression == null) return;
            if ((Globals.selectedEditor.SelectedExpression
                is LunarPresentation.Expressions.BaseText) == false) return;

            Command.EditBaseText(Globals.selectedEditor.SelectedExpression as LunarPresentation.Expressions.BaseText);
        }

        private void miEditFstBaseText_Click(object sender, RoutedEventArgs e)
        {
            Command.EditFstBaseText();
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            bool closed = CloseDocuments();
            if (closed == false) e.Cancel = true;
        }

        public bool CloseDocuments()
        {
            // 先查看有无已被修改的文档。有即提示。
            bool hasModifiedDocument = false;
            foreach (TabItem ti in mainTabControl.Items)
            {
                Editor editor = ti as Editor;
                if (editor != null && editor.IsModified)
                {
                    hasModifiedDocument = true;
                    break;
                }
            }

            if (hasModifiedDocument)
            {
                // 如果有文档未被保存，则提示。
                MessageBoxResult r = MessageBox.Show(
                    "发现有文档已被修改，要保存吗？", Globals.appName,
                    MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);
                switch (r)
                {
                    case MessageBoxResult.Yes:
                        {
                            Command.SaveAllFiles();
                            return true;
                        }
                    case MessageBoxResult.No:
                        {
                            return true;
                        }
                    default:
                        {
                            return false;
                        }
                }
            }
            else return true;
        }

        private void sliderOfBorderWidth_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            if (Globals.selectedEditor == null) return;
            if (Globals.selectedEditor.SelectedExpression == null) return;

            Expressions.Expression ex = Globals.selectedEditor.SelectedExpression;

            ModifingItem mi = new ModifingItem();
            Action action = new Action(ex.ExID, -1, ex.GetType().Name, "BorderWidth",
                ex.BorderWidth.ToString(), ((int)sliderOfBorderWidth.Value).ToString());

            ex.BorderWidth = (int)(sliderOfBorderWidth.Value);

            mi.Add(action);
            ex.Editor.Do(mi);
        }

        private void miSwitchDirection_Click(object sender, RoutedEventArgs e)
        {
            Command.SwitchDirection();
        }

        private void miBorderWhite_Click(object sender, RoutedEventArgs e)
        {
            Command.BorderColorLaunch(Brushes.White);
        }

        private void miBorderRed_Click(object sender, RoutedEventArgs e)
        {
            Command.BorderColorLaunch(Brushes.Red);
        }

        private void miBorderOrange_Click(object sender, RoutedEventArgs e)
        {
            Command.BorderColorLaunch(Brushes.Orange);
        }

        private void miBorderYellow_Click(object sender, RoutedEventArgs e)
        {
            Command.BorderColorLaunch(Brushes.Yellow);
        }

        private void miBorderGreen_Click(object sender, RoutedEventArgs e)
        {
            Command.BorderColorLaunch(Brushes.Green);
        }

        private void miBorderBrown_Click(object sender, RoutedEventArgs e)
        {
            Command.BorderColorLaunch(Brushes.Brown);
        }

        private void miBorderBlue_Click(object sender, RoutedEventArgs e)
        {
            Command.BorderColorLaunch(Brushes.Blue);
        }

        private void miBorderViolet_Click(object sender, RoutedEventArgs e)
        {
            Command.BorderColorLaunch(Brushes.Violet);
        }

        private void miBorderGray_Click(object sender, RoutedEventArgs e)
        {
            Command.BorderColorLaunch(Brushes.Gray);
        }

        private void miBorderTransparent_Click(object sender, RoutedEventArgs e)
        {
            Command.BorderColorLaunch(Brushes.Transparent);
        }

        private void miButtonInsertLineAtTop_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertLine(true);
        }

        private void miButtonInsertLineAtBottom_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertLine(false);
        }

        private void miButtonInsertLineAtLeft_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertColumn(true);
        }

        private void miButtonInsertLineAtRight_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertColumn(false);
        }

        private void miButtonMergeToRight_Click(object sender, RoutedEventArgs e)
        {
            Command.Merge(Command.MergeOperation.Right);
        }

        private void miButtonMergeToBottom_Click(object sender, RoutedEventArgs e)
        {
            Command.Merge(Command.MergeOperation.Bottom);
        }

        private void miButtonMergeCancel_Click(object sender, RoutedEventArgs e)
        {
            Command.Merge(Command.MergeOperation.Cancel);
        }

        private void miButtonDeleteLine_Click(object sender, RoutedEventArgs e)
        {
            Command.DeleteLine();
        }

        private void miButtonDeleteColumn_Click(object sender, RoutedEventArgs e)
        {
            Command.DeleteColumn();
        }

        private void btnAlignLeftOrTop_Click(object sender, RoutedEventArgs e)
        {
            Command.Align(Expressions.Expression.Alignment.LeftOrTop);
        }

        private void btnAlignCenter_Click(object sender, RoutedEventArgs e)
        {
            Command.Align(Expressions.Expression.Alignment.Center);
        }

        private void btnAlignRightOrBottom_Click(object sender, RoutedEventArgs e)
        {
            Command.Align(Expressions.Expression.Alignment.RightOrBottom);
        }

        private void btnAlignDefault_Click(object sender, RoutedEventArgs e)
        {
            Command.Align(Expressions.Expression.Alignment.Default);
        }

        private void miAlignLeftOrTop_Click(object sender, RoutedEventArgs e)
        {
            Command.Align(Expressions.Expression.Alignment.LeftOrTop);
        }

        private void miAlignCenter_Click(object sender, RoutedEventArgs e)
        {
            Command.Align(Expressions.Expression.Alignment.Center);
        }

        private void miAlignRightOrBottom_Click(object sender, RoutedEventArgs e)
        {
            Command.Align(Expressions.Expression.Alignment.RightOrBottom);
        }

        private void miAlignDefault_Click(object sender, RoutedEventArgs e)
        {
            Command.Align(Expressions.Expression.Alignment.Default);
        }

        private void miComment_Click(object sender, RoutedEventArgs e)
        {
            Command.Comment(this);
        }

        private void miEmbedToBracket_Click(object sender, RoutedEventArgs e)
        {
            Command.EmbedToBracket();
        }

        private void miEmbedToRow_Click(object sender, RoutedEventArgs e)
        {
            Command.EmbedToRow();
        }

        private void miEmbedToOneLTwoCGrid_Click(object sender, RoutedEventArgs e)
        {
            Command.EmbedToOneLTwoCGrid();
        }

        private void miEmbedAllChildrenToGrid_Click(object sender, RoutedEventArgs e)
        {
            Command.EmbedAllChildrenToGrid();
        }

        private void miInsertExpander_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertExpander();
            Globals.SelectFirstChildExpression();
        }

        private void miExpandAndCollapse_Click(object sender, RoutedEventArgs e)
        {
            Command.ExpandAndCollapse();
        }

        private void miEmbedToExpander_Click(object sender, RoutedEventArgs e)
        {
            Command.EmbedToExpander();
        }

        private void miInsertObjectiveItem_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertObjectiveItem();
            Globals.SelectFirstChildExpression();
        }

        private void miInsertSubjectiveItem_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertSubjectiveItem();
            Globals.SelectFirstChildExpression();
        }

        private void miInsertPictureBox_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertPictureBox();
        }

        private void miInsertArrow_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertArrow();
        }

        private void miInsertBrace_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertBrace();
        }

        private void miInsertEndBrace_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertBrace(true);
        }

        private void miInsertTriangle_Click(object sender, RoutedEventArgs e)
        {
            if (Command.InsertTriangle() != null)
            {
                Globals.SelectFirstChildExpression();
            }
        }

        private void miSwitchLineAndColumn_Click(object sender, RoutedEventArgs e)
        {
            Command.SwitchLineAndColumn();
        }

        private void miArrowStart_Click(object sender, RoutedEventArgs e)
        {
            Command.ArrowLocationSetup(Expressions.Arrow.ArrowLocation.Start);
        }

        private void miArrowEnd_Click(object sender, RoutedEventArgs e)
        {
            Command.ArrowLocationSetup(Expressions.Arrow.ArrowLocation.End);
        }

        private void miArrowAll_Click(object sender, RoutedEventArgs e)
        {
            Command.ArrowLocationSetup(Expressions.Arrow.ArrowLocation.All);
        }

        /// <summary>
        /// 设置为矛盾关系。
        /// </summary>
        private void miSetContradiction_Click(object sender, RoutedEventArgs e)
        {
            Command.SwitchToContradiction();
        }

        /// <summary>
        /// 设置为对立关系。
        /// </summary>
        private void miSetOpposite_Click(object sender, RoutedEventArgs e)
        {
            Command.SwitchToOpposite();
        }

        private bool forbiddenFontChangedEvent = false;

        public bool ForbiddenFontChangedEvent
        {
            get { return forbiddenFontChangedEvent; }
            set { forbiddenFontChangedEvent = value; }
        }

        private bool forbiddenFontSizeLevelEvent = false;

        public bool ForbiddenFontSizeLevelEvent
        {
            get { return forbiddenFontSizeLevelEvent; }
            set { forbiddenFontSizeLevelEvent = value; }
        }

        private void cbFont_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (forbiddenFontChangedEvent) return;

            if (Globals.selectedEditor == null) return;
            if (Globals.selectedEditor.SelectedExpression == null) return;
            if (Globals.selectedEditor.SelectedExpression is Expressions.BaseText)
            {
                Expressions.BaseText bt = Globals.selectedEditor.SelectedExpression as Expressions.BaseText;
                if (bt.FontName != cbFont.SelectedItem.ToString())
                {
                    ModifingItem mi = new ModifingItem();
                    Action action = new Action(bt.ExID, -1, bt.GetType().Name,
                        "FontName", bt.FontName, cbFont.SelectedItem.ToString());

                    bt.FontName = cbFont.SelectedItem.ToString();

                    mi.Add(action);
                    bt.Editor.Do(mi);
                }
            }
            else
            {
                if (Globals.selectedEditor.SelectedExpression is Expressions.MarkText)
                {
                    Expressions.MarkText mt = Globals.selectedEditor.SelectedExpression as Expressions.MarkText;
                    if (mt.FontName != cbFont.SelectedItem.ToString())
                    {
                        ModifingItem mi = new ModifingItem();
                        Action action = new Action(mt.ExID, -1, mt.GetType().Name,
                            "FontName", mt.FontName, cbFont.SelectedItem.ToString());

                        mt.FontName = cbFont.SelectedItem.ToString();

                        mi.Add(action);
                        mt.Editor.Do(mi);
                    }
                }
            }
        }

        private void miUnderLine_Click(object sender, RoutedEventArgs e)
        {
            if (Globals.selectedEditor == null) return;
            if (Globals.selectedEditor.SelectedExpression == null) return;
            if ((Globals.selectedEditor.SelectedExpression is Expressions.BaseText) == false) return;

            Expressions.BaseText bt = Globals.selectedEditor.SelectedExpression as Expressions.BaseText;

            ModifingItem mi = new ModifingItem();
            Action action = new Action(bt.ExID, -1, bt.GetType().Name,
                "UnderLine", bt.UnderLine.ToString(), (!bt.UnderLine).ToString());

            bt.UnderLine = !bt.UnderLine;

            mi.Add(action);
            bt.Editor.Do(mi);
        }

        private void miStrikeLine_Click(object sender, RoutedEventArgs e)
        {
            if (Globals.selectedEditor == null) return;
            if (Globals.selectedEditor.SelectedExpression == null) return;
            if ((Globals.selectedEditor.SelectedExpression is Expressions.BaseText) == false) return;

            Expressions.BaseText bt = Globals.selectedEditor.SelectedExpression as Expressions.BaseText;

            ModifingItem mi = new ModifingItem();
            Action action = new Action(bt.ExID, -1, bt.GetType().Name,
                "StrikeLine", bt.StrikeLine.ToString(), (!bt.StrikeLine).ToString());

            bt.StrikeLine = !bt.StrikeLine;

            mi.Add(action);
            bt.Editor.Do(mi);
        }

        private void miInsertMarkText_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertMarkText();
        }

        private void miMoveToPrevious_Click(object sender, RoutedEventArgs e)
        {
            Command.MoveToPrevious();
        }

        private void miMoveToNext_Click(object sender, RoutedEventArgs e)
        {
            Command.MoveToNext();
        }

        private void btnMoveToPrevious_Click(object sender, RoutedEventArgs e)
        {
            Command.MoveToPrevious();
        }

        private void btnMoveToNext_Click(object sender, RoutedEventArgs e)
        {
            Command.MoveToNext();
        }

        private void btnScrollLeft_Click(object sender, RoutedEventArgs e)
        {
            scvOfExLayersTree.LineLeft();
        }

        private void btnScrollRight_Click(object sender, RoutedEventArgs e)
        {
            scvOfExLayersTree.LineRight();
        }

        public void EnableStatusControls(Visibility visibility)
        {
            btnScrollLeft.Visibility = visibility;
            btnScrollRight.Visibility = visibility;
            scvOfExLayersTree.Visibility = visibility;
            fontSizeSlider.Visibility = visibility;
        }

        private void btnPreviewExpression_Click(object sender, RoutedEventArgs e)
        {
            if (Globals.selectedEditor == null)
            {
                MessageBox.Show("当前没有文档处于可编辑状态！", Globals.appName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (Globals.selectedEditor.SelectedExpression == null)
            {
                MessageBox.Show("请先选中一个公式作为粘贴位置！", Globals.appName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (Globals.selectedEditor.SelectedExpression is Expressions.SubPanel)
            {
                MessageBox.Show("粘贴位置不能是子面板，请另选一个普通公式！", Globals.appName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            string idString = (sender as Button).Tag.ToString();

            DataTable exTable = Globals.globalDataSetIn.Tables["Expressions"];
            foreach (DataRow row in exTable.Rows)
            {
                if (row["ID"].ToString() == idString)
                {
                    Clipboard.SetData(DataFormats.UnicodeText, row["ExpressionXml"].ToString());
                    Command.Paste();
                    return;
                }
            }

            MessageBox.Show("发生意外错误，未能将数据库中的公式粘贴到指定位置！", Globals.appName,
                MessageBoxButton.OK, MessageBoxImage.Warning);
        }

        private void miSaveExpressionToDataBase_Click(object sender, RoutedEventArgs e)
        {
            Command.SaveExpressionToDataBase();
        }

        private void miSwitchArrowKeyMode_Click(object sender, RoutedEventArgs e)
        {
            Command.SwitchArrowkeyMode();
        }

        private void btnDeleteExRecord_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show("删除数据库的记录将不可恢复，真的要继续吗？",
                Globals.appName, MessageBoxButton.YesNo, MessageBoxImage.Warning);
            if (result != MessageBoxResult.Yes) return;

            Globals.globalConnection.Open();
            DataTable exTable = Globals.globalDataSetIn.Tables["Expressions"];

            string idString = (sender as Button).Tag.ToString();

            string insertStr = "DELETE [Expressions.*] FROM Expressions WHERE id=" + idString;
            OleDbCommand myCommand = new OleDbCommand(insertStr, Globals.globalConnection);
            myCommand.ExecuteNonQuery();

            //删除数据库记录后，再删除内存数据集中的记录。
            //由于采用了数据绑定，当内存数据集中的记录被删除后，主界面也会相应改变。
            //ID号不会重复，因此不必使用倒序删除。
            for (int i = 0; i < exTable.Rows.Count; i++)
            {
                if (exTable.Rows[i]["ID"].ToString() == idString)
                {
                    exTable.Rows.RemoveAt(i);
                    break;
                }
            }

            Globals.globalConnection.Close();
        }

        private void Expander_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                e.Handled = true;
            }
        }

        private void Button_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                e.Handled = true;
            }
        }

        private void mFile_SubmenuOpened(object sender, RoutedEventArgs e)
        {
            if (Globals.selectedEditor == null)
            {
                miSaveToTemplateDirectory.IsEnabled = false;
                miOutportDocumentToImage.IsEnabled = false;
                miPageSetting.IsEnabled = false;
                miPrintDocument.IsEnabled = false;
            }
            else
            {
                miSaveToTemplateDirectory.IsEnabled = true;
                miOutportDocumentToImage.IsEnabled = true;
                miPageSetting.IsEnabled = true;
                miPrintDocument.IsEnabled = true;
            }
        }

        private void mEdit_SubmenuOpened(object sender, RoutedEventArgs e)
        {
            if (Globals.selectedEditor != null)
            {
                miUndo.IsEnabled = Globals.selectedEditor.ModifingsList.CanUndo;
                miRedo.IsEnabled = Globals.selectedEditor.ModifingsList.CanRedo;
            }
            else
            {
                miUndo.IsEnabled = false;
                miRedo.IsEnabled = false;
            }

            if (Globals.selectedEditor == null ||
                Globals.selectedEditor.SelectedExpression == null)
            {
                miEditBaseText.IsEnabled = false;
                miInsertBaseAtBottomOfSelectionExpression.IsEnabled = false;
                miInsertBaseAtTopOfSelectionExpression.IsEnabled = false;
                miInsertBaseAtLeftOfSelectionExpression.IsEnabled = false;
                miInsertBaseAtRightOfSelectionExpression.IsEnabled = false;

                miCut.IsEnabled = false;
                miCopy.IsEnabled = false;
                miPaste.IsEnabled = false;
                miPasteImage.IsEnabled = false;
                miDelete.IsEnabled = false;
                miMoveToPrevious.IsEnabled = false;
                miMoveToNext.IsEnabled = false;

                mWildcardExpression.IsEnabled = false;

                miShowExpressionAtTopLeft.IsEnabled = false;
                return;
            }

            miShowExpressionAtTopLeft.IsEnabled = true;

            if (Globals.selectedEditor.SelectedExpression is Expressions.SubPanel)
            {
                miEditBaseText.IsEnabled = false;
                miInsertBaseAtBottomOfSelectionExpression.IsEnabled = true;//这个有效。
                miInsertBaseAtTopOfSelectionExpression.IsEnabled = false;
                miInsertBaseAtLeftOfSelectionExpression.IsEnabled = false;
                miInsertBaseAtRightOfSelectionExpression.IsEnabled = false;

                Expressions.LeafPanel lp = Globals.selectedEditor.SelectedExpression as Expressions.LeafPanel;
                if (lp == null || lp.LeafType == Expressions.LeafPanel.LeafPanelType.Root)
                {
                    miCut.IsEnabled = false;
                    miCopy.IsEnabled = false;
                    miDelete.IsEnabled = false;
                }
                else
                {
                    miCut.IsEnabled = true;
                    miCopy.IsEnabled = true;
                    miDelete.IsEnabled = true;
                }

                miPaste.IsEnabled = true;//即使子面板也是可以支持粘贴的——会粘贴到子面板尾部。

                miPasteImage.IsEnabled = false;
                miMoveToPrevious.IsEnabled = false;
                miMoveToNext.IsEnabled = false;

                mWildcardExpression.IsEnabled = false;
            }
            else
            {
                miEditBaseText.IsEnabled = true;

                miInsertBaseAtBottomOfSelectionExpression.IsEnabled = true;
                miInsertBaseAtTopOfSelectionExpression.IsEnabled = true;
                if (Globals.selectedEditor.SelectedExpression.ParentPanel.Direction ==
                   System.Windows.Controls.Orientation.Vertical)
                {
                    miInsertBaseAtLeftOfSelectionExpression.Header = "插入文本块（左下）并编辑";
                    miInsertBaseAtRightOfSelectionExpression.Header = "插入文本块（右下）并编辑";
                }
                else
                {
                    miInsertBaseAtLeftOfSelectionExpression.Header = "插入文本块（前）并编辑";
                    miInsertBaseAtRightOfSelectionExpression.Header = "插入文本块（后）并编辑";
                }

                miCut.IsEnabled = true;
                miCopy.IsEnabled = true;

                string clipboardText = Clipboard.GetText(TextDataFormat.UnicodeText);
                BitmapSource clipboardImg = Clipboard.GetImage();
                if ((clipboardText != null && clipboardText.Length > 0) ||
                    clipboardImg != null)
                {
                    miPaste.IsEnabled = true;
                }
                else
                {
                    miPaste.IsEnabled = false;
                }

                if (Globals.selectedEditor.SelectedExpression.Parent is StackPanel)
                {
                    StackPanel sp = Globals.selectedEditor.SelectedExpression.Parent as StackPanel;
                    int index = sp.Children.IndexOf(Globals.selectedEditor.SelectedExpression);
                    if (index <= 0)
                    {
                        miMoveToPrevious.IsEnabled = false;
                    }
                    else
                    {
                        miMoveToPrevious.IsEnabled = true;
                    }

                    if (index >= sp.Children.Count - 1)
                    {
                        miMoveToNext.IsEnabled = false;
                    }
                    else
                    {
                        miMoveToNext.IsEnabled = true;
                    }
                }

                if (Clipboard.GetImage() != null)
                {
                    miPasteImage.IsEnabled = true;
                }
                else
                {
                    miPasteImage.IsEnabled = false;
                }

                miDelete.IsEnabled = true;
                miMoveToPrevious.IsEnabled = true;
                miMoveToNext.IsEnabled = true;

                mWildcardExpression.IsEnabled = true;
            }
        }

        private void mView_SubmenuOpened(object sender, RoutedEventArgs e)
        {
            if (Globals.selectedEditor == null)
            {
                miSwitchAssistPanelVisibility.IsEnabled = false;
                miSwitchAutoWrap.IsEnabled = false;
                miSetMaxTextWidth.IsEnabled = false;
                miBlendDocColors.IsEnabled = false;
            }
            else
            {
                miSwitchAssistPanelVisibility.IsEnabled = true;
                miSwitchAutoWrap.IsEnabled = true;
                miSetMaxTextWidth.IsEnabled = true;
                miBlendDocColors.IsEnabled = true;
            }

            TextFormattingMode tfm = TextOptions.GetTextFormattingMode(this);

            Image img = new Image();
            img.Width = img.Height = 16;
            img.Source = new BitmapImage(new Uri("pack://Application:,,,/LunarPresentation;component/Resources/Icons/Selected.png"));

            switch (tfm)
            {
                case TextFormattingMode.Display:
                    {
                        miTextOptionsFormatModeDisplay.Icon = img;
                        miTextOptionsFormatModeIdle.Icon = null;
                        break;
                    }
                default:
                    {
                        miTextOptionsFormatModeDisplay.Icon = null;
                        miTextOptionsFormatModeIdle.Icon = img;
                        break;
                    }
            }
        }

        private void mInsert_SubmenuOpened(object sender, RoutedEventArgs e)
        {
            bool enable = true;

            if (Globals.selectedEditor == null ||
                Globals.selectedEditor.SelectedExpression == null/* ||
                (Globals.selectedEditor.SelectedExpression is Expressions.SubPanel)*/)
            {
                enable = false;
            }

            miInsertBaseText.IsEnabled = enable;
            miInserRichText.IsEnabled = enable;
            miInsertBracket.IsEnabled = enable;
            miInsertExpander.IsEnabled = enable;
            miInsertPictureBox.IsEnabled = enable;
            miInsertArrow.IsEnabled = enable;
            miInsertLine.IsEnabled = enable;
            miInsertBrace.IsEnabled = enable;
            miInsertTriangle.IsEnabled = enable;
            miInsertMarkText.IsEnabled = enable;
            miInsertObjectiveItem.IsEnabled = enable;
            miInsertSubjectiveItem.IsEnabled = enable;
            mLogic.IsEnabled = enable;
            miInsertRow.IsEnabled = enable;
            miInsertTree.IsEnabled = enable;
        }

        private void mEmbed_SubmenuOpened(object sender, RoutedEventArgs e)
        {
            if (Globals.selectedEditor == null || Globals.selectedEditor.SelectedExpression == null)
            {
                miEmbedToBracket.IsEnabled = false;
                miEmbedToExpander.IsEnabled = false;
                miEmbedToRow.IsEnabled = false;
                miEmbedToOneLTwoCGrid.IsEnabled = false;
                miEmbedAllChildrenToGrid.IsEnabled = false;
                return;
            }

            if (Globals.selectedEditor.SelectedExpression is Expressions.SubPanel)
            {
                miEmbedToBracket.IsEnabled = false;
                miEmbedToExpander.IsEnabled = false;
                miEmbedToRow.IsEnabled = false;
                miEmbedToOneLTwoCGrid.IsEnabled = false;
            }
            else
            {
                miEmbedToBracket.IsEnabled = true;
                miEmbedToExpander.IsEnabled = true;
                miEmbedToRow.IsEnabled = true;
                miEmbedToOneLTwoCGrid.IsEnabled = true;
            }

            miEmbedAllChildrenToGrid.IsEnabled = true;
        }

        private void mFormat_SubmenuOpened(object sender, RoutedEventArgs e)
        {
            bool enable = true;

            if (Globals.selectedEditor == null ||
                Globals.selectedEditor.SelectedExpression == null)
            {
                enable = false;
            }

            Expressions.Expression curEx = Globals.selectedEditor.SelectedExpression;

            if (enable)
            {
                miBorderWidth.IsEnabled = enable;

                miSwitchDirection.IsEnabled = enable;

                sliderOfBorderWidth.Value = Globals.selectedEditor.SelectedExpression.BorderWidth;

                bool isBaseText = curEx is Expressions.BaseText;
                bool isMarkText = curEx is Expressions.MarkText;
                miBaseTextFormat.IsEnabled = isBaseText;

                if (isMarkText)
                {
                    miUnderLine.IsEnabled = false;
                    miStrikeLine.IsEnabled = false;
                }
                else
                {
                    miUnderLine.IsEnabled = true;
                    miStrikeLine.IsEnabled = true;
                }

                bool notSubPanel = !(curEx is Expressions.SubPanel);
                miIndent.IsEnabled = notSubPanel;
                miOutdent.IsEnabled = notSubPanel;
                miGetIdentLevel.IsEnabled = notSubPanel;
                miSetIdentLevel.IsEnabled = notSubPanel;

                miAlignment.IsEnabled = notSubPanel;
                miComment.IsEnabled = true;

                bool isArrow = curEx is Expressions.Arrow;
                miArrowLocation.IsEnabled = isArrow;

                bool isContradiction = curEx is Expressions.LogicContradiction;
                miSetContraOrOpposite.IsEnabled = isContradiction;

                if (curEx is SHomeWorkshop.LunarPresentation.Interfaces.ICollapsed)
                {
                    miExpandAndCollapse.IsEnabled = true;
                }
                else
                {
                    miExpandAndCollapse.IsEnabled = false;
                }

                if (isArrow)
                {
                    Expressions.Arrow curArrow = curEx as Expressions.Arrow;
                    switch (curArrow.Arrows)
                    {
                        case Expressions.Arrow.ArrowLocation.All:
                            {
                                miArrowAll.IsEnabled = false;
                                miArrowEnd.IsEnabled = true;
                                miArrowStart.IsEnabled = true;
                                break;
                            }
                        case Expressions.Arrow.ArrowLocation.End:
                            {
                                miArrowAll.IsEnabled = true;
                                miArrowEnd.IsEnabled = false;
                                miArrowStart.IsEnabled = true;
                                break;
                            }
                        case Expressions.Arrow.ArrowLocation.Start:
                            {
                                miArrowAll.IsEnabled = true;
                                miArrowEnd.IsEnabled = true;
                                miArrowStart.IsEnabled = false;
                                break;
                            }
                    }
                }

                if (isContradiction)
                {
                    Expressions.LogicContradiction curContradiction = curEx as Expressions.LogicContradiction;
                    if (curContradiction.IsJustContradict)
                    {
                        miSetContradiction.IsEnabled = false;
                        miSetOpposite.IsEnabled = true;
                    }
                    else
                    {
                        miSetContradiction.IsEnabled = true;
                        miSetOpposite.IsEnabled = false;
                    }
                }

                switch (curEx.Align)
                {
                    case Expressions.Expression.Alignment.Default:
                        {
                            miAlignDefault.IsEnabled = false;
                            miAlignLeftOrTop.IsEnabled = true;
                            miAlignRightOrBottom.IsEnabled = true;
                            miAlignCenter.IsEnabled = true;
                            break;
                        }
                    case Expressions.Expression.Alignment.LeftOrTop:
                        {
                            miAlignDefault.IsEnabled = true;
                            miAlignLeftOrTop.IsEnabled = false;
                            miAlignRightOrBottom.IsEnabled = true;
                            miAlignCenter.IsEnabled = true;
                            break;
                        }
                    case Expressions.Expression.Alignment.RightOrBottom:
                        {
                            miAlignDefault.IsEnabled = true;
                            miAlignLeftOrTop.IsEnabled = true;
                            miAlignRightOrBottom.IsEnabled = false;
                            miAlignCenter.IsEnabled = true;
                            break;
                        }
                    case Expressions.Expression.Alignment.Center:
                        {
                            miAlignDefault.IsEnabled = true;
                            miAlignLeftOrTop.IsEnabled = true;
                            miAlignRightOrBottom.IsEnabled = true;
                            miAlignCenter.IsEnabled = false;
                            break;
                        }
                }
            }
            else
            {
                miBaseTextFormat.IsEnabled = enable;
                miBorderWidth.IsEnabled = enable;
                miSwitchDirection.IsEnabled = enable;

                miExpandAndCollapse.IsEnabled = false;

                miIndent.IsEnabled = enable;
                miOutdent.IsEnabled = enable;
                miGetIdentLevel.IsEnabled = enable;
                miSetIdentLevel.IsEnabled = enable;

                miAlignment.IsEnabled = enable;
                miComment.IsEnabled = enable;

                miArrowLocation.IsEnabled = enable;
                miSetContraOrOpposite.IsEnabled = enable;
            }
        }

        private void mGrid_SubmenuOpened(object sender, RoutedEventArgs e)
        {
            bool enable = true;
            if (Globals.selectedEditor == null ||
                Globals.selectedEditor.SelectedExpression == null)
            {
                enable = false;
            }

            if (enable)
            {
                //bool notSubPanel = !(Globals.selectedEditor.SelectedExpression is Expressions.SubPanel);
                //miInsertGrid.IsEnabled = notSubPanel;

                bool isGridPanel = Globals.selectedEditor.SelectedExpression is Expressions.GridPanel;
                miGridOperations.IsEnabled = isGridPanel;

                bool isGrid = Globals.selectedEditor.SelectedExpression is Expressions.Grid;
                miSwitchLineAndColumn.IsEnabled = isGrid;

                if (isGrid || isGridPanel) miGridPanelAlignment.IsEnabled = true;
                else miGridPanelAlignment.IsEnabled = false;

                gridPanelAlignmentControl.IsCheckBoxsVisible = isGridPanel;
            }
            else
            {
                miInsertGrid.IsEnabled = false;
                miGridOperations.IsEnabled = false;
                miSwitchLineAndColumn.IsEnabled = false;
                miGridPanelAlignment.IsEnabled = false;
            }
        }

        private void btnNew_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            KeyboardDevice kd = e.KeyboardDevice;

            bool isShift = false;
            if ((kd.GetKeyStates(Key.LeftShift) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightShift) & KeyStates.Down) > 0)
            {
                isShift = true;
            }

            if (e.Key == Key.Tab && isShift)
            {
                mHelp.Focus();
                e.Handled = true;
            }
        }

        private void tbtnAutoLocationBaseTextEditor_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            KeyboardDevice kd = e.KeyboardDevice;

            bool isShift = false;
            if ((kd.GetKeyStates(Key.LeftShift) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightShift) & KeyStates.Down) > 0)
            {
                isShift = true;
            }

            if (e.Key == Key.Tab && !isShift)
            {
                mainTabControl.Focus();
            }
        }

        private void btnHelp_Click(object sender, RoutedEventArgs e)
        {
            miHelp_Click(sender, e);
        }

        private void btnHelp_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            KeyboardDevice kd = e.KeyboardDevice;

            bool isShift = false;
            if ((kd.GetKeyStates(Key.LeftShift) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightShift) & KeyStates.Down) > 0)
            {
                isShift = true;
            }

            if (e.Key == Key.Tab && !isShift)
            {
                mainTabControl.Focus();
            }
        }

        private void miSwitchAssistPanelVisibility_Click(object sender, RoutedEventArgs e)
        {
            SwitchAssistPanelVisibility();
        }

        private void SwitchAssistPanelVisibility()
        {
            if (mainTabControl.Items.Count <= 0) return;

            if (gcAssist.ActualWidth <= 0)
            {
                gcAssist.Width = new GridLength(320);
                toolTab.Visibility = Visibility.Visible;
                toolTabSplitter.Visibility = Visibility.Visible;
            }
            else
            {
                gcAssist.Width = new GridLength(0);
                toolTab.Visibility = Visibility.Collapsed;
                toolTabSplitter.Visibility = Visibility.Hidden;
            }
        }

        private void miShowExpressionAtTopLeft_Click(object sender, RoutedEventArgs e)
        {
            Command.LocateExpressionToTopAndLeft();
        }

        private void miInsertBaseAtTopOfSelectionExpression_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertBaseAtPreviewOfSelectionAndEdit();
        }

        private void miInsertBaseAtBottomOfSelectionExpression_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertAtNextAndEditBaseText();
        }

        private void miInsertBaseAtLeftOfSelectionExpression_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertBaseAtLeftBottomOfSelectionAndEdit();
        }

        private void miInsertBaseAtRightOfSelectionExpression_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertBaseAtRightBottomOfSelectionAndEdit();
        }

        private void miAsignWildcardExpression_Click(object sender, RoutedEventArgs e)
        {
            Command.AssignWildcardExpression();
        }

        private void miInsertWildcardExpression_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertWildcardExpression();
        }

        private void miOutportDocumentToImage_Click(object sender, RoutedEventArgs e)
        {
            Command.OutportDocumentToImage();
        }

        private void miOutportExpressionToImage_Click(object sender, RoutedEventArgs e)
        {
            Command.OutportExpressionToImage();
        }

        private void miCloseSelectedDocument_Click(object sender, RoutedEventArgs e)
        {
            if (Globals.selectedEditor != null)
            {
                Globals.selectedEditor.Close();
            }
        }

        private void SetImageOfToolButton(Object sender, string fileShortName)
        {
            ContentControl btn = sender as ContentControl;

            Image img = new Image();
            img.Width = img.Height = 16;
            if (btn.IsEnabled)
            {
                img.Source = new BitmapImage(new Uri("pack://Application:,,,/LunarPresentation;component/Resources/Icons/" + fileShortName));
            }
            else
            {
                img.Source = new BitmapImage(new Uri("pack://Application:,,,/LunarPresentation;component/Resources/Icons/" + "U_" + fileShortName));
            }
            btn.Content = img;
        }

        private void btnNew_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "NewDocumentHS.png");
        }

        private void btnOpen_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "openHS.png");
        }

        private void btnSave_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "saveHS.png");
        }

        private void btnCut_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "CutHS.png");
        }

        private void btnCopy_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "CopyHS.png");
        }

        private void btnPaste_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "PasteHS.png");
        }

        private void btnMoveToPrevious_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "MoveToPrevious.png");
        }

        private void btnMoveToNext_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "MoveToNext.png");
        }

        private void tbtnBold_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "boldhs.png");
        }

        private void tbtnItalic_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "ItalicHS.png");
        }

        private void btnOutdent_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "OutdentHS.png");
        }

        private void btnIndent_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "IndentHS.png");
        }

        private void tbtnFormatBrush_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "FormatBrushHS.png");
        }

        private void btnAlignLeftOrTop_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "AlignLeftOrTop.png");
        }

        private void btnAlignCenter_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "AlignCenter.png");
        }

        private void btnAlignRightOrBottom_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "AlignRightOrBottom.png");
        }

        private void btnAlignDefault_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "AlignDefault.png");
        }

        private void tbtnAutoLocationBaseTextEditor_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "Pin.png");
        }

        #region 菜单项图标变灰。
        private void SetMenuItemIcon(object sender, string fileShortName)
        {
            MenuItem mi = sender as MenuItem;

            Image img = new Image();
            img.Width = img.Height = 16;
            if (mi.IsEnabled)
            {
                img.Source = new BitmapImage(new Uri("pack://Application:,,,/LunarPresentation;component/Resources/Icons/" + fileShortName));
            }
            else
            {
                img.Source = new BitmapImage(new Uri("pack://Application:,,,/LunarPresentation;component/Resources/Icons/" + "U_" + fileShortName));
            }
            mi.Icon = img;
        }
        #endregion

        private void miSaveDocument_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetMenuItemIcon(sender, "SaveHS.png");
        }

        private void miSaveAllDocument_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetMenuItemIcon(sender, "SaveAllHS.png");
        }

        private void miCut_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetMenuItemIcon(sender, "CutHS.png");
        }

        private void miCopy_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetMenuItemIcon(sender, "CopyHS.png");
        }

        private void miPaste_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetMenuItemIcon(sender, "PasteHS.png");
        }

        private void miIndent_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetMenuItemIcon(sender, "IndentHS.png");
        }

        private void miOutdent_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetMenuItemIcon(sender, "OutdentHS.png");
        }


        #region 网格菜单项按钮图标变灰。
        private void SetGridMenuItemButtonImage(Button sender, bool isEnabled, string fileShortName)
        {
            Image img = new Image();
            img.Width = img.Height = 16;
            if (isEnabled)
            {
                img.Source = new BitmapImage(new Uri("pack://Application:,,,/LunarPresentation;component/Resources/Icons/" + fileShortName));
            }
            else
            {
                img.Source = new BitmapImage(new Uri("pack://Application:,,,/LunarPresentation;component/Resources/Icons/" + "U_" + fileShortName));
            }
            sender.Content = img;
        }
        #endregion

        private void miGridOperations_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetGridMenuItemButtonImage(miButtonMergeToRight, miGridOperations.IsEnabled, "MergeToRight.png");
            SetGridMenuItemButtonImage(miButtonMergeToBottom, miGridOperations.IsEnabled, "MergeToBottom.png");
            SetGridMenuItemButtonImage(miButtonMergeCancel, miGridOperations.IsEnabled, "MergeCancel.png");

            SetGridMenuItemButtonImage(miButtonDeleteLine, miGridOperations.IsEnabled, "DeleteLine.png");
            SetGridMenuItemButtonImage(miButtonDeleteColumn, miGridOperations.IsEnabled, "DeleteColumn.png");
            SetGridMenuItemButtonImage(miButtonInsertLineAtTop, miGridOperations.IsEnabled, "InsertLineAtTop.png");

            SetGridMenuItemButtonImage(miButtonInsertLineAtBottom, miGridOperations.IsEnabled, "InsertLineAtBottom.png");
            SetGridMenuItemButtonImage(miButtonInsertLineAtLeft, miGridOperations.IsEnabled, "InsertColumnAtLeft.png");
            SetGridMenuItemButtonImage(miButtonInsertLineAtRight, miGridOperations.IsEnabled, "InsertColumnAtRight.png");

            if (miGridOperations.IsEnabled)
            {
                gridMiBorder.BorderBrush = Brushes.Red;
            }
            else
            {
                gridMiBorder.BorderBrush = Brushes.Gray;
            }
        }

        /// <summary>
        /// 根据常用配色方案对文本块进行配色。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            TextBlock tb = sender as TextBlock;
            SetBaseTextColor(tb.Background, tb.Foreground);
        }

        /// <summary>
        /// 此方法只能由SetBaseTextColor()方法调用。
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="newBorderColor"></param>
        private static void SetExBorderColorAndWidth(Expressions.Expression ex, Brush newBorderColor)
        {
            if (ex == null || newBorderColor == null) return;

            ModifingItem mi = new ModifingItem() { OldSelectedExID = ex.ExID, NewSelectedExID = ex.ExID };

            if (ex.BorderColor != newBorderColor)
            {
                Action actBorderColor = new Action(ex.ExID, -1, ex.GetType().Name, "BorderColor",
                    ColorPicker.GetBrushName(ex.BorderColor), ColorPicker.GetBrushName(newBorderColor));
                ex.BorderColor = newBorderColor;
                mi.Add(actBorderColor);
            }

            int newWidth = 4;

            if (ex.BorderWidth != newWidth)
            {
                Action actBorderWidth = new Action(ex.ExID, -1, ex.GetType().Name, "BorderWidth",
                    ex.BorderWidth.ToString(), newWidth.ToString());
                ex.BorderWidth = newWidth;
                mi.Add(actBorderWidth);
            }

            ex.Editor.Do(mi);
            ex.Editor.IsModified = true;
        }

        /// <summary>
        /// 设置文本块前景色和背景色。如果当前公式不是文本块，且
        /// <paramref name="autoSetBorderColorAndWidth"/>的值为true，
        /// 则会设置前景色到公式的边框，并将边框色设置为４，而背景色参数将被抛弃（不作处理）。
        /// </summary>
        /// <param name="autoSetBorderColorAndWidth">
        /// 为真时，会自动设置边框色为前景色、边框宽度为４。
        /// 注：边框选用前景而不是背景是为了避免边框与背景色混合——那会看不出来的
        /// ——而前景色一般与背景色不同。</param>
        private static void SetBaseTextColor(Brush background, Brush foreground, bool autoSetBorderColorAndWidth = false)
        {
            if (Globals.selectedEditor == null ||
                Globals.selectedEditor.SelectedExpression == null)
            {
                MessageBox.Show("请先选中一个公式！", Globals.appName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            Expressions.BaseText bt = Globals.selectedEditor.SelectedExpression as Expressions.BaseText;
            if (bt == null)
            {
                if (autoSetBorderColorAndWidth)
                {
                    SetExBorderColorAndWidth(Globals.selectedEditor.SelectedExpression, foreground);
                    return;
                }
                else
                {
                    MessageBox.Show("请先选中一个文本块！", Globals.appName,
                        MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
            }
            else
            {
                ModifingItem mi = new ModifingItem();

                //Action actBack = new Action(bt.ExID, -1, bt.GetType().Name, "TextBackground",
                //   ColorPicker.GetBrushName(bt.TextBackground), ColorPicker.GetBrushName(tb.Background));
                //bt.TextBackground = tb.Background;

                Action actBack = new Action(bt.ExID, -1, bt.GetType().Name, "ExBackground",
                   ColorPicker.GetBrushName(bt.ExBackground), ColorPicker.GetBrushName(background));
                bt.ExBackground = background;

                Action actFore = new Action(bt.ExID, -1, bt.GetType().Name, "ExForeground",
                   ColorPicker.GetBrushName(bt.ExForeground), ColorPicker.GetBrushName(foreground));
                bt.ExForeground = foreground;

                mi.Add(actBack); mi.Add(actFore);

                if (autoSetBorderColorAndWidth)
                {
                    if (bt.BorderColor != foreground)
                    {
                        Action actBorderColor = new Action(bt.ExID, -1, bt.GetType().Name, "BorderColor",
                            ColorPicker.GetBrushName(bt.BorderColor), ColorPicker.GetBrushName(foreground));
                        bt.BorderColor = foreground;
                        mi.Add(actBorderColor);
                    }

                    int newWidth = 4;

                    if (bt.BorderWidth != newWidth)
                    {
                        Action actBorderWidth = new Action(bt.ExID, -1, bt.GetType().Name, "BorderWidth",
                            bt.BorderWidth.ToString(), newWidth.ToString());
                        bt.BorderWidth = newWidth;
                        mi.Add(actBorderWidth);
                    }
                }

                if (bt.Editor != null)
                {
                    bt.Editor.IsModified = true;
                    bt.Editor.Do(mi);
                }
            }
        }

        private void miGetIdentLevel_Click(object sender, RoutedEventArgs e)
        {
            Command.GetIndentLevel();
        }

        private void miSetIdentLevel_Click(object sender, RoutedEventArgs e)
        {
            Command.SetIndentLevel();
        }

        private void miUndo_Click(object sender, RoutedEventArgs e)
        {
            Command.Undo();
        }

        private void miRedo_Click(object sender, RoutedEventArgs e)
        {
            Command.Redo();
        }

        private void miUndo_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetMenuItemIcon(sender, "Edit_UndoHS.png");
        }

        private void miRedo_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetMenuItemIcon(sender, "Edit_RedoHS.png");
        }

        private void tbtnBold_Click(object sender, RoutedEventArgs e)
        {
            if (Command.Bold() == false)
            {
                tbtnBold.IsChecked = !tbtnBold.IsChecked;
            }
        }

        private void tbtnItalic_Click(object sender, RoutedEventArgs e)
        {
            if (Command.Italic() == false)
            {
                tbtnItalic.IsChecked = !tbtnItalic.IsChecked;
            }
        }

        private void tbtnFormatBrush_Click(object sender, RoutedEventArgs e)
        {
            if (tbtnFormatBrush.IsChecked.Value)
            {
                bool multiFormatBrush = false;
                bool isLeftCtrlDown = System.Windows.Input.Keyboard.IsKeyDown(Key.LeftCtrl);
                bool isRightCtrlDown = System.Windows.Input.Keyboard.IsKeyDown(Key.RightCtrl);
                multiFormatBrush = isLeftCtrlDown || isRightCtrlDown;

                SetFormatDataForGlobalsClass(multiFormatBrush);
            }
            else
            {
                Globals.BaseTextFormatBrush = null;
            }
        }

        private void SetFormatDataForGlobalsClass(bool multiFormatBrush)
        {
            if (Globals.selectedEditor == null ||
                Globals.selectedEditor.SelectedExpression == null ||
                (Globals.selectedEditor.SelectedExpression is Expressions.BaseText) == false)
            {
                MessageBox.Show("请先选中一个文本块！", Globals.appName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            Expressions.BaseText bt = Globals.selectedEditor.SelectedExpression as Expressions.BaseText;

            Globals.BaseTextFormatBrush = new BaseTextFormat()
            {
                FontStyle = bt.FontStyle,
                FontWeight = bt.FontWeight,
                ExBackground = bt.ExBackground,
                //ExForeground = bt.ExForeground,
                BorderBrush = bt.BorderColor,
                BorderWidth = bt.BorderWidth,
                Indent = bt.Indent,
                UnderLine = bt.UnderLine,
                StrikeLine = bt.StrikeLine,
                IsMuiltFormatBrush = multiFormatBrush,
                FontName = bt.FontName,
                FontSizeLevel = bt.FontSizeLevel,
                IsHeaderText = bt.IsHeaderText,
                Align = bt.Align,
                Mask = bt.Mask,
                SourceExID = bt.ExID,
            };

            //自启用标题文本块自定义“默认前景色”后，事情变得更复杂了。
            XmlAttribute attrForeground = bt.XmlData.GetAttribute("ExForeground");
            if (attrForeground == null)
            {
                Globals.BaseTextFormatBrush.ExForeground = null;//这将决定格式刷、撤销、重做等行为。
            }
            else
            {
                Globals.BaseTextFormatBrush.ExForeground = bt.ExForeground;
            }
        }

        private void miFullScreen_Click(object sender, RoutedEventArgs e)
        {
            SwitchFullScreen();
        }

        private void mTools_SubmenuOpened(object sender, RoutedEventArgs e)
        {
            if (Globals.pathOfExpressionDatabase == null)
            {
                miSaveExpressionToDataBase.Visibility = Visibility.Collapsed;
                miSearchDataBase.Visibility = Visibility.Collapsed;
            }
            else
            {
                miSaveExpressionToDataBase.Visibility = Visibility.Visible;
                miSearchDataBase.Visibility = Visibility.Visible;
            }

            if (Globals.selectedEditor == null)
            {
                miInputCommand.IsEnabled = false;
                miTryLoadExFromOutportedExImage.IsEnabled = false;
            }
            else
            {
                miInputCommand.IsEnabled = true;

                if (Globals.selectedEditor.SelectedExpression == null)
                {
                    miSaveExpressionToDataBase.IsEnabled = false;
                    miCopyToImage.IsEnabled = false;
                    miCopyAsOutLine.IsEnabled = false;
                    miOutportExpressionToImage.IsEnabled = false;

                    miTryLoadExFromOutportedExImage.IsEnabled = false;
                }
                else
                {
                    miCopyToImage.IsEnabled = true;
                    miCopyAsOutLine.IsEnabled = true;
                    miOutportExpressionToImage.IsEnabled = true;

                    if (Globals.selectedEditor.SelectedExpression is Expressions.SubPanel)
                    {
                        miSaveExpressionToDataBase.IsEnabled = false;
                    }
                    else
                    {
                        miSaveExpressionToDataBase.IsEnabled = true;
                    }

                    miTryLoadExFromOutportedExImage.IsEnabled = true;
                }
            }
        }

        private void miTextOptionsFormatModeDisplay_Click(object sender, RoutedEventArgs e)
        {
            TextOptions.SetTextFormattingMode(this, TextFormattingMode.Display);
        }

        private void miTextOptionsFormatModeIdle_Click(object sender, RoutedEventArgs e)
        {
            TextOptions.SetTextFormattingMode(this, TextFormattingMode.Ideal);
        }

        private void miSwitchAutoWrap_Click(object sender, RoutedEventArgs e)
        {
            Command.SwitchDocAutoWrap();
        }

        #region 用于定位拾色器位置的三个绑定。

        private Binding exForegroundBinding = null;

        private Binding exBackgroundBinding = null;

        private Binding exBorderColorBinding = null;

        #endregion

        private void btnExForeground_Click(object sender, RoutedEventArgs e)
        {
            if (Globals.colorPickerPopup.IsOpen)
            {
                Globals.colorPickerPopup.IsOpen = false;
            }

            if (exForegroundBinding == null)
            {
                exForegroundBinding = new Binding();
                exForegroundBinding.Source = btnExForeground;
            }

            Globals.colorPickerPopup.SetBinding(Popup.PlacementTargetProperty, exForegroundBinding);

            ColorPicker colorpicker = Globals.colorPickerPopup.Child as ColorPicker;
            colorpicker.DestAction = ColorPicker.Destination.Foreground;
            Globals.colorPickerPopup.IsOpen = true;
        }

        private void btnExForeground_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "Foreground.png");
        }

        private void btnExBackground_Click(object sender, RoutedEventArgs e)
        {
            if (Globals.colorPickerPopup.IsOpen)
            {
                Globals.colorPickerPopup.IsOpen = false;
            }

            if (exBackgroundBinding == null)
            {
                exBackgroundBinding = new Binding();
                exBackgroundBinding.Source = btnExBackground;
            }

            Globals.colorPickerPopup.SetBinding(Popup.PlacementTargetProperty, exBackgroundBinding);

            ColorPicker colorpicker = Globals.colorPickerPopup.Child as ColorPicker;
            colorpicker.DestAction = ColorPicker.Destination.Background;
            Globals.colorPickerPopup.IsOpen = true;
        }

        private void btnExBackground_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "Background.png");
        }

        private void btnExBoarderColor_Click(object sender, RoutedEventArgs e)
        {
            if (Globals.colorPickerPopup.IsOpen)
            {
                Globals.colorPickerPopup.IsOpen = false;
            }

            if (exBorderColorBinding == null)
            {
                exBorderColorBinding = new Binding();
                exBorderColorBinding.Source = btnExBoarderColor;
            }

            Globals.colorPickerPopup.SetBinding(Popup.PlacementTargetProperty, exBorderColorBinding);

            ColorPicker colorpicker = Globals.colorPickerPopup.Child as ColorPicker;
            colorpicker.DestAction = ColorPicker.Destination.Border;
            Globals.colorPickerPopup.IsOpen = true;
        }

        private void btnExBoarderColor_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "BorderColor.png");
        }

        private void btnExEraseAllColors_Click(object sender, RoutedEventArgs e)
        {
            Command.ExEraseAllColors();
        }

        private void btnExEraseAllColors_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            SetImageOfToolButton(sender, "Erase.png");
        }

        private void cbTextHeaderLevel_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (ForbiddenFontSizeLevelEvent) return;
            //在选中文本块时，要刷新组合框的选择项，此时不应引起连锁反应。

            if (Globals.selectedEditor == null) return;
            if (Globals.selectedEditor.SelectedExpression == null) return;

            if (Globals.selectedEditor.SelectedExpression is Expressions.BaseText)
            {
                Expressions.BaseText bt = Globals.selectedEditor.SelectedExpression as Expressions.BaseText;

                ModifingItem mi = new ModifingItem() { OldSelectedExID = bt.ExID, NewSelectedExID = bt.ExID };

                int newFontSizeLevel = int.Parse((cbTextHeaderLevel.SelectedItem as ComboBoxItem).Tag.ToString());
                string className = bt.GetType().Name;

                Action actFontSizeLevel = new Action(bt.ExID, -1, className, "FontSizeLevel",
                    bt.FontSizeLevel.ToString(), newFontSizeLevel.ToString());
                bt.FontSizeLevel = newFontSizeLevel;
                mi.Add(actFontSizeLevel);


                //只有１到４级是标题，余者均不是。
                bool isHeaderText = false;
                switch (bt.FontSizeLevel)
                {
                    case 1:
                    case 2:
                    case 3:
                    case 4: { isHeaderText = true; break; }
                    default: { isHeaderText = false; break; }
                }

                if (bt.IsHeaderText != isHeaderText)
                {
                    Action actIsHeaderText = new Action(bt.ExID, -1, className, "IsHeaderText",
                        bt.IsHeaderText.ToString(), isHeaderText.ToString());

                    bt.IsHeaderText = isHeaderText;
                    mi.Add(actIsHeaderText);
                }

                if (bt.FontSizeLevel == 0)
                {
                    //正文可以在任意缩进级别。因此此处不作修正。

                    //正文不加粗。
                    if (bt.FontWeight != FontWeights.Normal)
                    {
                        Action actFontWeight = new Action(bt.ExID, -1, className, "FontWeight",
                            bt.FontWeight.ToString(), FontWeights.Normal.ToString());
                        bt.FontWeight = FontWeights.Normal;

                        mi.Add(actFontWeight);
                    }

                    //正文不倾斜。
                    if (bt.FontStyle != FontStyles.Normal)
                    {
                        Action actFontStyle = new Action(bt.ExID, -1, className, "FontStyle",
                            bt.FontStyle.ToString(), FontStyles.Normal.ToString());
                        bt.FontStyle = FontStyles.Normal;

                        mi.Add(actFontStyle);
                    }

                    //正文不加下划线。
                    if (bt.UnderLine)
                    {
                        Action actUnderLine = new Action(bt.ExID, -1, className, "UnderLine",
                            bt.UnderLine.ToString(), false.ToString());
                        bt.UnderLine = false;

                        mi.Add(actUnderLine);
                    }

                    //正文不加删除线。
                    if (bt.StrikeLine)
                    {
                        Action actStrikeLine = new Action(bt.ExID, -1, className, "StrikeLine",
                            bt.StrikeLine.ToString(), false.ToString());
                        bt.StrikeLine = false;

                        mi.Add(actStrikeLine);
                    }
                }
                else if (bt.FontSizeLevel >= 1 && bt.FontSizeLevel <= 4)
                {
                    //if (bt.FontSizeLevel % 2 == 0)//本来标题是间隔层级加粗的。
                    //{
                    if (bt.FontSizeLevel == 4)//此处本来是>0——后来只保留了一、级标题的加粗。
                    {
                        if (bt.FontWeight != FontWeights.Bold)
                        {
                            Action actFontWeight = new Action(bt.ExID, -1, className, "FontWeight",
                                bt.FontWeight.ToString(), FontWeights.Bold.ToString());
                            bt.FontWeight = FontWeights.Bold;

                            mi.Add(actFontWeight);
                        }
                    }
                    else//正文本不应加粗。
                    {
                        if (bt.FontWeight != FontWeights.Normal)
                        {
                            Action actFontWeight = new Action(bt.ExID, -1, className, "FontWeight",
                                bt.FontWeight.ToString(), FontWeights.Normal.ToString());
                            bt.FontWeight = FontWeights.Normal;

                            mi.Add(actFontWeight);
                        }
                    }

                    if (bt.FontStyle != FontStyles.Normal)
                    {
                        Action actFontStyle = new Action(bt.ExID, -1, className, "FontStyle",
                            bt.FontStyle.ToString(), FontStyles.Normal.ToString());
                        bt.FontStyle = FontStyles.Normal;

                        mi.Add(actFontStyle);
                    }
                    //}
                    //else
                    //{
                    //    Action actFontWeight = new Action(bt.ExID, -1, className, "FontWeight",
                    //        bt.FontWeight.ToString(), FontWeights.Normal.ToString());
                    //    bt.FontWeight = FontWeights.Normal;

                    //    Action actFontStyle = new Action(bt.ExID, -1, className, "FontStyle",
                    //        bt.FontStyle.ToString(), FontStyles.Normal.ToString());
                    //    bt.FontStyle = FontStyles.Normal;

                    //    mi.Add(actFontWeight);
                    //    mi.Add(actFontStyle);
                    //}

                    int indent = 4 - bt.FontSizeLevel;

                    //if (bt.Indent != indent)//需要解决“自动编号”的刷新问题。
                    //{
                    Action actIndent = new Action(bt.ExID, -1, className, "Indent",
                        bt.Indent.ToString(), indent.ToString());
                    bt.Indent = indent;
                    mi.Add(actIndent);
                    //}

                    //垂直子面板中，默认对齐是左齐。
                    if (bt.Align != Expressions.Expression.Alignment.Default)
                    {
                        Action actAlign = new Action(bt.ExID, -1, className, "Align",
                                bt.Align.ToString(),
                                Expressions.Expression.Alignment.Default.ToString());
                        bt.Align = Expressions.Expression.Alignment.Default;
                        mi.Add(actAlign);
                    }
                }
                else if (bt.FontSizeLevel == 5)//顶级副标题
                {
                    if (bt.Indent != 0)
                    {
                        int indent = 0;
                        Action actIndent = new Action(bt.ExID, -1, className, "Indent",
                                bt.Indent.ToString(), indent.ToString());
                        bt.Indent = indent;
                        mi.Add(actIndent);
                    }

                    if (bt.Align != Expressions.Expression.Alignment.RightOrBottom)
                    {
                        Action actAlign = new Action(bt.ExID, -1, className, "Align",
                                bt.Align.ToString(),
                                Expressions.Expression.Alignment.RightOrBottom.ToString());
                        bt.Align = Expressions.Expression.Alignment.RightOrBottom;
                        mi.Add(actAlign);
                    }

                    //顶级副标题默认不加粗。
                    if (bt.FontWeight == FontWeights.Bold)
                    {
                        Action actFontWeight = new Action(bt.ExID, -1, className,
                            "FontWeight", bt.FontWeight.ToString(), FontWeights.Normal.ToString());
                        bt.FontWeight = FontWeights.Normal;

                        mi.Add(actFontWeight);
                    }
                }
                else if (bt.FontSizeLevel == 6)//顶级标题
                {
                    if (bt.Indent != 0)
                    {
                        int indent = 0;
                        Action actIndent = new Action(bt.ExID, -1, className, "Indent",
                                bt.Indent.ToString(), indent.ToString());
                        bt.Indent = indent;
                        mi.Add(actIndent);
                    }

                    if (bt.Align != Expressions.Expression.Alignment.Center)
                    {
                        Action actAlign = new Action(bt.ExID, -1, className, "Align",
                                bt.Align.ToString(),
                                Expressions.Expression.Alignment.Center.ToString());
                        bt.Align = Expressions.Expression.Alignment.Center;
                        mi.Add(actAlign);
                    }

                    //顶级标题一般作为整个文本的标题。默认加粗。
                    if (bt.FontWeight != FontWeights.Bold)
                    {
                        Action actFontWeight = new Action(bt.ExID, -1, className,
                            "FontWeight", bt.FontWeight.ToString(), FontWeights.Bold.ToString());
                        bt.FontWeight = FontWeights.Bold;

                        mi.Add(actFontWeight);
                    }
                }

                if (bt.ParentPanel != null)
                {
                    bt.ParentPanel.RefreshAutoNumbersOfBaseText();
                }

                bt.RefreshText();
                bt.Editor.Do(mi);
                bt.Editor.SelectedExpression = bt;//这是为了刷新相关按钮的状态。
            }
            else if (Globals.selectedEditor.SelectedExpression is Expressions.MarkText)
            {
                Expressions.MarkText mt = Globals.selectedEditor.SelectedExpression as Expressions.MarkText;

                ModifingItem mi = new ModifingItem() { OldSelectedExID = mt.ExID, NewSelectedExID = mt.ExID };

                int newFontSizeLevel = int.Parse((cbTextHeaderLevel.SelectedItem as ComboBoxItem).Tag.ToString());
                string className = mt.GetType().Name;

                Action actFontSizeLevel = new Action(mt.ExID, -1, className, "FontSizeLevel",
                    mt.FontSizeLevel.ToString(), newFontSizeLevel.ToString());

                mt.FontSizeLevel = newFontSizeLevel;
                mi.Add(actFontSizeLevel);

                if (mt.FontSizeLevel % 2 == 0)
                {
                    if (mt.FontSizeLevel > 0)
                    {
                        Action actFontWeight = new Action(mt.ExID, -1, className, "FontWeight",
                            mt.FontWeight.ToString(), FontWeights.Bold.ToString());
                        mt.FontWeight = FontWeights.Bold;

                        mi.Add(actFontWeight);
                    }//正文本不应加粗。
                    else
                    {
                        if (mt.FontWeight != FontWeights.Normal)
                        {
                            Action actFontWeight = new Action(mt.ExID, -1, className, "FontWeight",
                            mt.FontWeight.ToString(), FontWeights.Normal.ToString());
                            mt.FontWeight = FontWeights.Normal;

                            mi.Add(actFontWeight);
                        }
                    }

                    Action actFontStyle = new Action(mt.ExID, -1, className, "FontStyle",
                        mt.FontStyle.ToString(), FontStyles.Normal.ToString());
                    mt.FontStyle = FontStyles.Normal;

                    mi.Add(actFontStyle);
                }
                else
                {
                    Action actFontWeight = new Action(mt.ExID, -1, className, "FontWeight",
                        mt.FontWeight.ToString(), FontWeights.Normal.ToString());
                    mt.FontWeight = FontWeights.Normal;

                    mi.Add(actFontWeight);
                }

                mt.Editor.Do(mi);
                mt.Editor.SelectedExpression = mt;//这是为了刷新相关按钮的状态。
            }
        }

        /// <summary>
        /// 根据指定的值选中“样式”框中相应的项。
        /// </summary>
        /// <param name="fontSizeLevel"></param>
        public void RefreshFontSizeLevel(int fontSizeLevel)
        {
            ForbiddenFontSizeLevelEvent = true;
            if (fontSizeLevel >= 0 && fontSizeLevel <= 4)
            {
                cbTextHeaderLevel.SelectedIndex = 7 - fontSizeLevel;
            }
            else if (fontSizeLevel >= 5 && fontSizeLevel <= 6)//添加了一条分隔线。
            {
                cbTextHeaderLevel.SelectedIndex = 6 - fontSizeLevel;
            }
            else
            {
                cbTextHeaderLevel.SelectedIndex = -1;
            }
            ForbiddenFontSizeLevelEvent = false;
        }

        private void tbtnTopMost_Click(object sender, RoutedEventArgs e)
        {
            if (tbtnTopMost.IsChecked == true)
                this.Topmost = true;
            else
                this.Topmost = false;
        }

        private void miOpenDatabaseFolder_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start("explorer.exe",
                $"\"{Globals.pathOfMyDocuments + "\\SHome WorkShop\\Lunar Presentation"}\"");
        }

        private void miOpenInstalledFolder_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Process.Start("explorer.exe", $"\"{Globals.installedPath}\"");
        }

        private void tbxShortCutInfo_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            ExContextMenus.ShowHelpFile("shortCuts.htm");
        }

        /// <summary>
        /// 主窗口启动时，从Xml文件中载入命令。
        /// 此方法只应由主窗口的Load事件调用一次。
        /// 
        /// 此方法会从一个Xml文件中读取每一个条目，并添加到fdCommandsList中。
        /// </summary>
        private void LoadTextComds()
        {
            //TODO 载入命令列表。
            string textCmdXmlFilePath = Globals.installedPath + "Cmds.xml";
            if (File.Exists(textCmdXmlFilePath) != true) return;

            try
            {
                XDocument xDoc = XDocument.Load(textCmdXmlFilePath);
                if (xDoc.Root == null) return;

                foreach (XElement cmdSetElement in xDoc.Root.Elements())
                {
                    Paragraph newParagraph = new Paragraph();
                    fdCommandsList.Blocks.Add(newParagraph);

                    newParagraph.Inlines.Add(new Run(cmdSetElement.Attribute("Name").Value)
                    {
                        Foreground = Brushes.Red,
                        FontSize = 14,
                        FontWeight = FontWeights.Bold,
                    });

                    newParagraph.Inlines.Add(new LineBreak());
                    newParagraph.Inlines.Add(new LineBreak());

                    foreach (XElement cmdElement in cmdSetElement.Elements())
                    {
                        string cmdText = cmdElement.Attribute("CmdText").Value;
                        newParagraph.Inlines.Add(
                            new Hyperlink(new Run(cmdElement.Attribute("Name").Value))
                            {
                                TargetName = cmdText,
                            });
                        newParagraph.Inlines.Add(new Run(" 命令：" + cmdText)
                        {
                            Foreground = Brushes.Red
                        });

                        newParagraph.Inlines.Add(new LineBreak());
                        newParagraph.Inlines.Add(
                            new Run(cmdElement.Value) { Foreground = Brushes.Gray });

                        newParagraph.Inlines.Add(new LineBreak());
                        newParagraph.Inlines.Add(new LineBreak());
                    }
                }
            }
            catch (Exception ex)
            {
                Dialogs.LunarMsgBox.MsgBoxShow(
                    Globals.appName,
                    "未能顺利完成载入文本命令列表操作。",
                    "异常信息如下：\r\n" + ex.Message,
                    ex.StackTrace, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
        }

        //从主界面调用命令。
        private void fdCommandsList_Click(object sender, RoutedEventArgs e)
        {
            Hyperlink hLink = e.Source as Hyperlink;
            if (hLink == null || hLink.TargetName == null ||
                hLink.TargetName.Length <= 0) return;

            string cmdText = hLink.TargetName.ToString();

            if (cmdText.Contains("{") && cmdText.Contains("}"))
            {
                MessageBox.Show("此命令需要提供参数，必须在“命令模式”下使用键盘输入才可执行。",
                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            int index = cmdText.IndexOf("|");
            if (index >= 0)
            {
                cmdText = cmdText.Substring(0, index);
            }

            Command.RunTextCmd(cmdText);
        }

        private void hLinkCmdMode_Click(object sender, RoutedEventArgs e)
        {
            OpenCommandMode();
        }

        private void hLinkShowCmdInputBoxDialog_Click(object sender, RoutedEventArgs e)
        {
            Command.InputCommand(this);
        }

        private void miInsertLine_Click(object sender, RoutedEventArgs e)
        {
            Command.InsertHorizontalLine();
        }

        private void miSaveToTemplateDirectory_Click(object sender, RoutedEventArgs e)
        {
            Command.SaveTemplateDocument();
        }

        private void miNewFileFromTemplate_Click(object sender, RoutedEventArgs e)
        {
            Dialogs.NewDocDialog ndlg = new Dialogs.NewDocDialog() { Owner = Globals.MainWindow };
            ndlg.ShowDialog();

            // 为防止主窗口快捷键失效，令Editor的ScrollViewer获取焦点。
            Globals.MainWindow.Focus();
            Globals.SwitchInputMethod(false);
        }

        private void miTryLoadExFromOutportedExImage_Click(object sender, RoutedEventArgs e)
        {
            LunarPresentation.Dialogs.LoadExFromOutportedExImageDlg ldlg =
                new Dialogs.LoadExFromOutportedExImageDlg() { Owner = Globals.MainWindow };

            if (Globals.selectedEditor == null) return;

            if (Globals.selectedEditor == null)
            {
                e.Handled = true;
                MessageBox.Show("当前未打开任何文档，此操作没有目标！", Globals.appName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (Globals.selectedEditor.SelectedExpression == null)
            {
                e.Handled = true;
                MessageBox.Show("请先在当前文档中选择一个公式（不能是子面板）作为尝试恢复的位置！", Globals.appName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            Expressions.BaseText curBt = Globals.selectedEditor.SelectedExpression as Expressions.BaseText;
            if (curBt != null && curBt.IsCollapsed)
            {
                MessageBox.Show("请先展开当前标题文本块！", Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            Expressions.SubPanel curSubPanel = Globals.selectedEditor.SelectedExpression as Expressions.SubPanel;
            if (curSubPanel != null)
            {
                MessageBox.Show("请先选取一个（非子面板）的普通公式作为恢复的基准位置！",
                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            bool? dlgResult = ldlg.ShowDialog();

            // 为防止主窗口快捷键失效，令Editor的ScrollViewer获取焦点。
            Globals.MainWindow.Focus();
            Globals.SwitchInputMethod(false);
        }

        private void miSetMaxTextWidth_Click(object sender, RoutedEventArgs e)
        {
            Command.SetMaxTextWidth();
        }

        private void miBlendDocColors_Click(object sender, RoutedEventArgs e)
        {
            if (Globals.selectedEditor == null)
            {
                MessageBox.Show("当前没有打开任何文档！", Globals.appName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            LunarPresentation.Dialogs.DocBackgroundImageDlg dbiDlg =
                new Dialogs.DocBackgroundImageDlg(Globals.selectedEditor);
            dbiDlg.ShowDialog();

            // 为防止主窗口快捷键失效，令Editor的ScrollViewer获取焦点。
            Globals.MainWindow.Focus();
            Globals.SwitchInputMethod(false);
        }

        private void miPageSetting_Click(object sender, RoutedEventArgs e)
        {
            Command.PageSetting();
        }

        private void miPrintDocument_Click(object sender, RoutedEventArgs e)
        {
            Command.PrintSelectedDocument();
        }

        private void miGridPanelAlignment_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            gridPanelAlignmentControl.IsEnabled = miGridPanelAlignment.IsEnabled;
        }

        private void Window_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.MiddleButton == MouseButtonState.Pressed)
            {
                if (this.WindowState == WindowState.Maximized)
                {
                    this.WindowState = WindowState.Normal;
                }
                else if (this.WindowState == WindowState.Normal)
                {
                    this.WindowState = WindowState.Maximized;
                }
                e.Handled = true;
            }
        }

        private void miCopyAsOutLine_Click(object sender, RoutedEventArgs e)
        {
            Commands.Command.CopyAsOutLine();
        }
    }
}
